Scheduler
core/scheduler, cron.tick and how addons register periodic work.
sys.cron
core/scheduler ticks on an interval (server starts it about every minute), selects due active cron rows inside a transaction with FOR UPDATE SKIP LOCKED, publishes cron.tick, and optionally a custom event_name.
When running multiple Sumeru instances against one database, row locks prevent duplicate execution of the same cron job. See Multi-instance cron.
Addon registration
Addons typically define cron rows via data XML and/or subscribe to cron.tick (as automation does). Interval comes from interval_number (minutes).
RegisterCronHandler
When a sys.cron row fires, the scheduler looks up a Go handler registered by code:
scheduler.RegisterCronHandler("my_module.nightly_digest", func(ctx context.Context, payload map[string]interface{}) error { // periodic work return nil})
You must seed a matching sys.cron row. CRM’s lead-assign event is not bundled as cron — use Assign Leads on the team form.
See Events & automation for declarative server actions and outbox behaviour.
Compile and run
make run # scheduler starts with the HTTP server
What not to do
- Do not expect cron to run if the HTTP process is down.
- Do not schedule multi-hour blocking jobs directly on the tick handler.
Next step
See ephemeral storage in Cache.