Class Eddyq
Index
Constructors
Accessors
Methods
Accessors
line
- get line(): string
The migration line this client was built for (default:
"main").Returns string
Methods
addIntervalSchedule
- addIntervalSchedule(
name: string,
intervalMs: number,
kind: string,
payload: any,
options?: ScheduleOptions | null,
): Promise<void>Register a fixed-interval schedule (
{ every: ms }). Fires everyintervalMsmilliseconds — no cron expression required. Skip-missed semantics: a delayed fire doesn't catch up, matching the cron path and the Redis backend.Parameters
- name: string
- intervalMs: number
- kind: string
- payload: any
Optionaloptions: ScheduleOptions | null
Returns Promise<void>
addSchedule
- addSchedule(
name: string,
cronExpr: string,
kind: string,
payload: any,
options?: ScheduleOptions | null,
): Promise<void>Upsert a cron schedule. Jobs of
kindwith the givenpayloadwill be enqueued automatically each time the cron fires. Passing the samenameupdates the schedule in place.Cron syntax is a 6- or 7-field
sec min hour day month dayOfWeek [year]expression (thecroncrate's dialect — note the leading seconds field).await queue.addSchedule(
"daily-report",
"0 0 8 * * *", // every day at 08:00:00 UTC
"report.generate",
{ scope: "daily" },
{ priority: 5 },
);Parameters
- name: string
- cronExpr: string
- kind: string
- payload: any
Optionaloptions: ScheduleOptions | null
Returns Promise<void>
cancel
Cancel a pending job. Returns
trueif cancelled,falseif the job doesn't exist or is already running / finalized (handlers must cooperate to stop a running job — eddyq can't abort it for you).Parameters
- id: number
Returns Promise<boolean>
clean
- clean(
graceMs: number,
limit: number,
state: "completed" | "failed" | "cancelled",
): Promise<number>Ad-hoc retention sweep. Deletes up to
limitfinalized jobs instateolder thangraceMsmilliseconds.stateis one of"completed" | "failed" | "cancelled". Returns the number of rows actually deleted.Parameters
- graceMs: number
- limit: number
- state: "completed" | "failed" | "cancelled"
Returns Promise<number>
clearGroupRate
Parameters
- groupKey: string
Returns Promise<void>
close
Close the underlying Postgres pool and release any retained NAPI
ThreadsafeFunctions. Call on shutdown.Defensive in two ways:
- If
shutdown()was never called and the queue isRunning, we run an internalAbandonshutdown (drops runtime without awaiting handlers, leaves DB rows for heartbeat-sweep recovery). This isn't graceful — callers shouldawait queue.shutdown()first — but it guaranteesclose()can't hang the process. - The abort TSFN is dropped if
shutdown()didn't already.
After
close(), no further calls on thisEddyqinstance are valid.Returns Promise<void>
- If
enqueue
Enqueue a job.
payloadis serialized as JSON and passed to the worker registered forkind.Parameters
- kind: string
- payload: any
Optionaloptions: EnqueueOptions | null
Returns Promise<EnqueueOutcome>
enqueueBatch
Enqueue a batch of jobs and (optionally) a callback that fires when every item reaches terminal state. Native fan-in primitive — replaces the per-app counter table workaround for "run X after these N jobs."
The callback's payload gets a namespaced envelope:
{ _eddyq_batch: { batchId, total, completed, failed, cancelled, durationMs }, ...userPayload }. Handler branches onfailed/cancelledcounts to decide what success vs partial-failure means in its domain.Items skipped via
uniqueKeydedup do not count toward the batch'stotal— they belong to the batch that originally enqueued them. The returnedskippedreports the count for the caller's logging.Parameters
- input: EnqueueBatchInput
Returns Promise<BatchEnqueueOutcome>
enqueueMany
Enqueue a batch of jobs in a single round-trip. Uses a Postgres
UNNEST-based INSERT, so 1000 jobs cost roughly one statement instead of one per job. Mixedkindwithin a batch is supported.Returns aggregate counts (
inserted,skipped); per-job ids are not surfaced — use a stableuniqueKeyper item if you need to correlate results back to your own domain objects, or fall back toenqueue()when you need the auto-generated id.Batch size is capped at 5,000 items per call — split larger workloads client-side.
Parameters
- items: EnqueueManyItem[]
Returns Promise<BulkEnqueueOutcome>
getStats
Job counts grouped by (queue, state). One SQL query — use as the landing query for a dashboard.
Returns Promise<JobStats>
listGroups
Every group that has an explicit row (cap, pause, rate-limit state).
Returns Promise<Group[]>
listJobs
Paginated job listing with optional filters. Defaults: limit=50, offset=0. Limit caps at 500.
Parameters
Optionalfilter: ListJobsFilter | nullOptionalpagination: Pagination | null
Returns Promise<JobList>
listNamedQueues
Every named queue that has an explicit row (concurrency cap, pause state, etc.). Queues with no row are implicitly unlimited and not returned here — use
getStats()to see all queues with live jobs.Returns Promise<NamedQueue[]>
listSchedules
Every registered cron schedule.
Returns Promise<Schedule[]>
migrate
Apply all pending schema migrations.
Returns Promise<MigrateReport>
migrateDown
migrationStatus
Full migration status (all known versions, applied or pending).
Returns Promise<MigrationStatus[]>
pauseGroup
Parameters
- groupKey: string
Returns Promise<void>
pauseQueue
Parameters
- queue: string
Returns Promise<void>
removeSchedule
Remove a schedule. Returns
trueif a row was deleted.Parameters
- name: string
Returns Promise<boolean>
resumeGroup
Parameters
- groupKey: string
Returns Promise<void>
resumeQueue
Parameters
- queue: string
Returns Promise<void>
setAbortHandler
Register a handler invoked when
shutdown()is called. The handler'sreasonarg is a human-readable string; the JS ergonomics layer (lib.cjs) uses this to broadcast.abort()to all in-flightAbortControllers, so user handlers observingcall.signalcan bail.Most users don't call this directly — lib.cjs wires it automatically.
Parameters
- handler: (reason: string) => void
Returns void
setGroupConcurrency
Cap concurrent running jobs in
group_key. Jobs withenqueue(..., { groupKey })respect this cap across all workers.Parameters
- groupKey: string
- max: number
Returns Promise<void>
setGroupRate
Token-bucket rate limit: at most
countjobs may start perperiodMsmilliseconds in this group.Parameters
- groupKey: string
- count: number
- periodMs: number
Returns Promise<void>
setQueueConcurrency
Cap total running jobs on a named queue across all worker processes.
Parameters
- queue: string
- max: number
Returns Promise<void>
setQueueTimeout
Set a default per-job timeout (milliseconds) for this named queue. Pass
nullto clear.Parameters
- queue: string
OptionaltimeoutMs: number | null
Returns Promise<void>
setScheduleEnabled
Toggle a schedule on or off without deleting it. Returns
trueif a row was updated.Parameters
- name: string
- enabled: boolean
Returns Promise<boolean>
setWorkerConcurrency
Set worker concurrency (max in-flight jobs in this process). Default 10. Must be called before
start().Parameters
- n: number
Returns void
shutdown
Stop the worker runtime. Signals any registered abort handler first, then waits up to
gracefulTimeoutMs(default 30 000) for in-flight jobs to finish before forcibly cancelling the runtime tasks. Admin methods remain usable after shutdown — callclose()to release the DB pool entirely.On return, all NAPI
ThreadsafeFunctionreferences this binding holds are dropped (handler TSFNs via the worker registry, plus the abort TSFN). That releases their libuv ref counts so Node's event loop can drain naturally — without that drop, a Nestapp.close()on SIGTERM would call this method but the process would still hang until the orchestrator force-killed it.options.mode:"drain"(default) — graceful: stop claiming new jobs, fireAbortSignalto in-flight handlers, await up togracefulTimeoutMs. Use for routine deploys."force"— fast: abort runtime tasks immediately and proactively reclaim rows this pod was processing (set running→pending) so other pods pick them up without waiting for heartbeat sweep. Use when SIGKILL is imminent (Kubernetes grace period almost up)."abandon"— last-resort: drop runtime, leave rows alone. The heartbeat sweep on another pod will recover afterstaleAfter. Use only on panic exits.
Parameters
Optionaloptions: ShutdownOptions | null
Returns Promise<void>
start
Start the worker runtime. Handlers registered via
work()begin processing jobs from Postgres. Fetch/sweep/scheduler loops run untilshutdown()is called.Pending-migration guard. Before starting, checks that every migration the binary knows about has been applied. If any are missing,
start()errors out with a clear message instead of booting workers that will trip on missing columns. Pass{ skipMigrationCheck: true }to override (e.g. when schema is managed by a separate deploy step).Async so the internal
tokio::spawns land on napi's tokio runtime.Parameters
Optionaloptions: StartOptions | null
Returns Promise<void>
subscribeTo
Subscribe this worker to specific named queues. Default
["default"]. Must be called beforestart().Parameters
- queues: string[]
Returns void
syncSchedules
Reconcile DB schedules against a code-declared list. Each entry is upserted; any DB schedule whose name is not in
declaredis deleted. Idempotent — safe to run on every boot. Use this when schedules are declared in module config (e.g.EddyqModule.forRoot({ schedules })).Parameters
- declared: ScheduleDeclaration[]
Returns Promise<SyncSchedulesReport>
work
Register an async JS handler for a job kind. Call once per kind before
start(). The handler receives aJobCallobject and should resolve on success or throw/reject to trigger a retry.await queue.work("send.email", async ({ payload, id, attempt }) => {
await sendgrid.send(payload);
});Parameters
- kind: string
- handler: (call: JobCall) => Promise<unknown>
Returns void
Parameters
- kind: string
- handler: (call: JobCall) => Promise<unknown>
Returns void
Staticconnect
Connect to Postgres and construct a client. Does not run migrations — call
migrate()on first boot (or on app deploy).Parameters
- databaseUrl: string
Optionaloptions: ConnectOptions | null
Returns Promise<Eddyq>
Connection to eddyq. Owns a Postgres pool; share a single instance across your app and call
close()on shutdown.Exposed to JS as
Eddyq— the Rust struct staysQueueinternally.