Background Tasks & Scheduling
Dracory runs background work through two complementary systems: a persistent
task queue backed by the taskstore package, and a
cron-style scheduler built on github.com/go-co-op/gocron.
Task Queue
Tasks are durable units of work stored in the database and executed by a worker pool. The queue
only runs when the task store is enabled (taskStoreUsed = true in
internal/config/stores_config.go).
On boot, tasks.RegisterTasks(app) (called from cmd/server/main.go)
registers every handler, and a taskstore.TaskQueueRunner is started in
cmd/server/background_processes.go with 10 workers, a 2-second poll interval, and a
2-minute unstuck timeout on the default queue.
Defining a Task
-
Create a package under
internal/tasks/<name>/implementingtaskstore.TaskHandlerInterface. Existing examples includehello_world,clean_up,email_otp, andstats. -
Add a compile-time safe alias constant in
internal/tasks/constants/constants.go. -
Register the handler in
internal/tasks/register_tasks.goso it is added to the task store at startup.
Enqueueing Tasks
Tasks can be enqueued from controllers or other code paths:
// Via the handler instance
_, err := email_otp.NewEmailOTPTask(app).Enqueue(nonce)
// Or by alias through the task store
_, err := app.GetTaskStore().TaskDefinitionEnqueueByAlias(ctx,
taskstore.DefaultQueueName, constants.EmailOTPTaskAlias,
map[string]any{"nonce": nonce})
Running Tasks from the CLI
Any task can be executed synchronously from the command line by alias:
go run ./cmd/server task HelloWorldTask
See the CLI Commands page for the full command list.
Scheduled Jobs
Recurring work is declared in internal/schedules/ using gocron.
schedules.StartAsync(ctx, app) is launched as a background goroutine at boot and
stops when the server context is cancelled:
func newScheduler(app app.AppInterface) *gocron.Scheduler {
scheduler := gocron.NewScheduler(time.UTC)
// Example: run a task every 20 minutes
scheduler.Every(20).Minutes().Do(func() {
scheduleCleanUpTask(app)
})
return scheduler
}
Each scheduled job lives in its own file (for example
schedule_clean_up.go, schedule_blind_index_rebuild.go) and typically
enqueues a task rather than doing heavy work inline, so failures are retried by the queue.
Other Background Processes
background_processes.go also starts store housekeeping goroutines when enabled:
- Cache expiry sweeper (cache store)
- Session expiry sweeper (session store)