feat(queue): add typed application queue lifecycle
This commit is contained in:
@@ -118,6 +118,45 @@ await queue.add("email", { to: "a@b.com" }, { delayMs: 5000, maxAttempts: 3 });
|
||||
queue.start(); // begin polling; queue.stop() to halt
|
||||
```
|
||||
|
||||
### Application queues with `defineQueue`
|
||||
|
||||
WrNexus applications can place typed queue modules in `app/queues`. The dev and
|
||||
production servers discover them, start them after runtime initialization, and
|
||||
shut them down gracefully:
|
||||
|
||||
```ts
|
||||
import { defineQueue } from "@wrnexus/queue";
|
||||
|
||||
export default defineQueue({
|
||||
name: "email",
|
||||
jobs: {
|
||||
send: {
|
||||
maxAttempts: 3,
|
||||
idempotency: ({ messageId }: { messageId: number }) => `message:${messageId}`,
|
||||
run: async ({ messageId }) => sendMessage(messageId),
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Callers get a typed producer and inspection helpers:
|
||||
|
||||
```ts
|
||||
const job = await email.send.add({ messageId: 42 });
|
||||
await email.send.status(job.id);
|
||||
await email.send.cancel(job.id);
|
||||
await email.send.retry(job.id);
|
||||
```
|
||||
|
||||
`createDurableQueue` also exposes `start()`, `stop()`, `isRunning()`, `health()`
|
||||
and `get()` so applications do not need to build their own polling middleware.
|
||||
|
||||
### SQLite
|
||||
|
||||
Use `sqliteQueueStore(db)` from `@wrnexus/queue/sqlite` with a WrNexus-compatible
|
||||
SQLite client. `installSqliteQueueSchema(db)` installs the queue table and its
|
||||
due-job and idempotency indexes.
|
||||
|
||||
Use `context.signal` in network/database calls so forced shutdown and active
|
||||
cancellation finish promptly. For process termination, prefer
|
||||
`await queue.shutdown()`; use `{ force: true }` only after your grace period.
|
||||
|
||||
Reference in New Issue
Block a user