Open cloutiertyler opened 1 month ago
I believe this is possibly already implemented, but we should use this ticket to make sure we're happy with the current design.
Yes we have that: init
is called on the first publish, and update
is called on every subsequent update (aka publish-without-dash-c). Both are transactional, i.e. if the reducers return an error, nothing is committed to the database and either no database is running (on init
), or the old database continues running (on update
).
One thing I would like to review for the current design is that if your update
function is not idempotent, then publishing a module twice without changing the code will apply the effects twice which might be surprising behavior. Not sure if we care about that though.
Perhaps we just remove this capability and leave it's implementation to be run as a migration with the migration UX
Possible solution: when you publish a database update you can optionally specify a function to call when the update is applied. e.g.:
#[spacetimedb(init)]
pub fn init(...) {}
// This macro makes it possible to call this reducer during update
#[spacetimedb(update)]
pub fn do_module_update(...) {}
Then to publish:
spacetime publish -s --update='do_module_update' my_module_name
I like the idea of doing this via migrations -- as timer tables are just tables, even spawning a repeated task would fit into the model.
Perhaps we just remove this capability
Maybe replace with migrations.
Callback when publishing without -c
Problem
The BitCraft team wants some custom logic to execute when they publish a module without using
-c
. One thing Alexander wants to be able to do is change the duration of a scheduled reducer (because the durations are part of the static data, which they can update from the client).Proposed Solution #1
We could add a callback function that is analogous to the
init(..)
function, except its executed when publishing without-c
. Basically in this newupdate(..)
function he could lookup any scheduled reducers, cancel them all, and then reschedule them with the new updated value.Perhaps we decorate like this:
This solution is in the same vein as a migration handler. As specified here this function would not have any ability to migrate any data, but it would give you a handle to be able to do operations on your module
Some questions to answer before we move forward on this:
init
is called when you publish with-c
andmodule_updated(..)
is also called when you publish with-c
, but when you publish without-c
onlymodule_updated(..)
is called.Proposed Solution #2
(pasted from comments section)
For now we could just tell the BitCraft team to refactor their code. Any code that manages repeating reducers should be in a new reducer called
manage_reducers(..)
. This reducer would be called frominit
, but it would also be manually invoked after publishing without-c
.This ticket is about number 1 here:*