Schedulers
Shiva provides a server-side Scheduler global for registering named, cancellable repeating tasks. Use it instead of raw Citizen.CreateThread loops — it adds error isolation, logging, and clean cancellation.
Registering a Task
lua
Scheduler.every('mymodule:saveData', 5 * 60 * 1000, function()
-- runs every 5 minutes
DB.exec('UPDATE players SET last_seen = NOW() WHERE online = 1')
end)The first argument is a unique task name. Use modulename:taskname to avoid collisions.
Cancelling a Task
lua
Scheduler.cancel('mymodule:saveData')Cancellation is safe to call even if the task is not currently running.
Cancelling All Tasks
lua
Scheduler.cancelAll()Useful in a module's stop() hook to clean up before unload.
Listing Active Tasks
lua
local tasks = Scheduler.active() -- returns string[]Error Handling
Errors thrown inside a task function are caught automatically, logged via Log.error, and the task continues running. A single task error will not kill the thread or affect other tasks.
lua
Scheduler.every('mymodule:riskyTask', 10000, function()
local ok = doSomethingThatMightFail()
-- if this throws, the error is logged and the next tick still runs
end)Full Example — Auto-save in a Module
lua
-- boot.lua
AddEventHandler('module:boot', function(ctx)
local container = ctx.container
-- Start auto-save every 3 minutes
Scheduler.every('mymodule:autosave', 3 * 60 * 1000, function()
local playerService = container:make('IPlayer')
local players = playerService:online()
for _, player in ipairs(players) do
player:save()
end
Log.info('mymodule', 'Auto-save complete', { count = #players })
end)
end)
AddEventHandler('module:stop', function()
Scheduler.cancel('mymodule:autosave')
end)API Reference
| Method | Description |
|---|---|
Scheduler.every(name, intervalMs, fn) | Register and immediately start a repeating task |
Scheduler.cancel(name) | Cancel a named task |
Scheduler.cancelAll() | Cancel all running tasks |
Scheduler.active() | Returns a list of active task name strings |
Server-only
Scheduler is a server-side global. It is not available in client scripts.