npm
Source
Description
@wolfstar/plugin-scheduled-tasks runs tasks later or on a schedule, such as unmuting a member in an hour or sending a
report every morning. It is the counterpart of
@sapphire/plugin-scheduled-tasks for
@wolfstar/http-framework.
Tasks are pieces. BullMQ stores their jobs in Redis, so jobs survive a restart and every
process of the bot shares them.
The plugin requires @wolfstar/http-framework 6.1.0 or later and a Redis server.
Registering the plugin
With thestars CLI, list the package in modules and set its options under the scheduledTasks key. It needs the
optional @wolfstar/kit peer dependency, at ^0.2.0 || ^0.3.0.
stars.config.ts
scheduledTasks key of stars.config. The [specifier, options] tuple of modules
still works. Its options are merged over the scheduledTasks key, so they win.
The optional @wolfstar/schema peer dependency types the scheduledTasks key in defineConfig.
TypeScript only loads that type once the module is imported, so import @wolfstar/plugin-scheduled-tasks in stars.config.ts.
The CLI writes options from stars.config into the built entry, so they must be JSON-serialisable.
Without the CLI, or to pass an ioredis instance, give the plugin to the client:
ClientOptions.tasks is merged over the plugin’s options, so you can also set the connection there:
modules or plugins, not both. Registering the plugin twice runs its hooks twice and starts two workers on
the same queue. The @wolfstar/plugin-scheduled-tasks/register entrypoint exists for the CLI and does nothing.
If no bull.connection is set in either place, the plugin throws a TypeError when the client initializes.
In
ClientOptions, tasks accepts bull, queue, ready, readyTimeout, and readyDelay, and loadScheduledTaskErrorListeners overrides
loadErrorListeners.
Writing a task
A task is a piece of thescheduled-tasks store, placed in the scheduled-tasks directory:
src/scheduled-tasks/unmute.ts
ScheduledTasks interface types the payload everywhere. Use never for a task without a payload, and a union with
undefined for an optional one.
Scheduling a task
create returns the BullMQ job. The second argument is either a delay in milliseconds or an options object with
delay, interval, or pattern and timezone, plus optional customJobOptions.
container.tasks.client is the BullMQ Queue itself.
Repeated tasks
A task with aninterval in milliseconds or a cron pattern is scheduled when the client starts listening:
src/scheduled-tasks/report.ts
timezone defaults to UTC. A repeated task is a BullMQ job scheduler
named after the task. Changing the pattern or interval in your code replaces its schedule on the next start.
Deleting the piece does not delete the scheduler from Redis. Remove it with container.tasks.deleteRepeated('report'),
and list existing schedulers with container.tasks.listRepeated().
Waiting for the app to be ready
When the worker starts, it immediately takes any job that came due while the bot was down. That can happen before the app has what the task needs, such as the gateway cache. Use theready option to tell the plugin when the app is ready,
and set waitForReady: true on the tasks that depend on it.
ready returns true, or a promise that resolves to anything but false, when the app is ready:
src/scheduled-tasks/poststats.ts
waitForReady task runs, its job waits up to readyTimeout for ready. If ready returns false, the
plugin calls it again every 250 ms until the timeout. If the app is still not ready, the plugin moves the job back to
delayed for readyDelay and the client emits scheduledTaskNotReady. The delayed job costs no attempt and does not
emit scheduledTaskError. If ready throws or rejects, the job fails like a task error.
- Tasks without
waitForReadynever wait.waitForReadydefaults tofalse. waitForReadydoes nothing if you don’t setready.- The worker runs one job at a time, so a waiting job holds back the other tasks for up to
readyTimeout. Lower it if that matters.
container.tasks.waitForReady(). It resolves to true once the app is ready, or
false if it still isn’t after the timeout. It defaults to readyTimeout, and resolves to true immediately without a
ready option:
Events
The client emits these events, whose names are inScheduledTaskEvents:
scheduledTaskRun,scheduledTaskSuccess,scheduledTaskError,scheduledTaskFinished, andscheduledTaskNotFoundaround every run.scheduledTaskNotReadywhen a task that waits for the app is delayed because the app isn’t ready. The plugin installs no listener for it, so add one if you want to log it.scheduledTaskStrategyConnectError,scheduledTaskStrategyClientError, andscheduledTaskStrategyWorkerErrorfor Redis and BullMQ failures.
attempts, which you set with
customJobOptions.
Shutting down
Differences from @sapphire/plugin-scheduled-tasks
- It runs on BullMQ 6, where repeated tasks are job schedulers.
listRepeated()returnsJobSchedulerJson[], anddeleteRepeated(name)is new. - The worker starts once the pieces are loaded rather than when the handler is constructed. A job is never taken before its task exists.
ClientOptions.tasksis optional, since you can give the options to the plugin instead.