Skip to content

Function: scheduleEntrypoint() ​

scheduleEntrypoint(options?): EntrypointAdapter<ScheduleContext<{ }>>

Create the schedule adapter of an entrypoint: it runs the controller actions declared with @Schedule, which never run without it. It needs no optional dependency.

The runs begin once the application has launched (all its objects, its bootstrap and the other adapters are ready). Each run is dispatched like a request: a new controller in its own scope, the middlewares and the access control, a ScheduleContext giving the schedule, the time the run was due and its number. An interval keeps its pace: the runs missed while the process was suspended are skipped, not caught up. An action whose previous run is still in progress skips its run unless it allows overlap.

An exclusive action runs in one instance of the application at a time: each run first tries to acquire a lock named schedule:<key> (the key of its exclusive option, the action name by default) from the mutex component (the Mutex of lakutata/com/mutex, named mutex by default), and is skipped when another instance holds it; the lock is kept after the run for half of its period (30 seconds at most) so that the instances whose clocks are late skip it too. An exclusive action whose mutex component cannot be resolved never runs (the error is logged).

When the entrypoint stops, no new run starts, the kept locks are released and the entrypoint waits for the runs in progress (aborting them after its shutdownTimeout).

Parameters ​

options? ​

ScheduleEntrypointOptions

The adapter options.

Returns ​

EntrypointAdapter<ScheduleContext<{ }>>

The adapter, to give to the schedule option of buildEntrypoints.

Example ​

typescript
import {Application} from 'lakutata'
import {buildEntrypoints, Controller, ScheduleContext, scheduleEntrypoint} from 'lakutata/com/entrypoint'
import {Schedule} from 'lakutata/decorator/ctrl'

class MaintenanceController extends Controller {
    //Every 5 minutes, and once the application launched
    @Schedule({every: '5m', immediate: true})
    public async purge(): Promise<void> {
        const context: ScheduleContext = this.context as ScheduleContext
        console.log(`Run ${context.run}, due at ${context.scheduledAt.toISOString()}`)
    }

    //Every day at 03:00 in Shanghai
    @Schedule({cron: '0 3 * * *', timezone: 'Asia/Shanghai'})
    public async report(): Promise<void> {
    }
}

Application.run({
    id: 'worker.app',
    name: 'Worker',
    components: {
        entrypoint: buildEntrypoints({
            controllers: [MaintenanceController],
            schedule: scheduleEntrypoint({
                onError: (error, action): void => console.error(`${action.name} failed`, error),
                onSkip: (action, scheduledAt, reason): void => console.warn(`${action.name} skipped (${reason})`)
            })
        })
    },
    bootstrap: ['entrypoint']
})

Released under the MIT License.