You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Throw an error to trigger retry. After `maxRetries`, the task fails permanently.
110
111
112
+
The handler receives an `AbortSignal` as its third argument (also available as `task.signal`) that aborts when the per-task `timeout` fires. Pass it to anything that supports cancellation so the work stops instead of running detached while a retry begins.
113
+
114
+
```js
115
+
queue.process(async (payload, task, signal) => {
116
+
constres=awaitfetch(payload.url, { signal })
117
+
returnawaitres.json()
118
+
})
119
+
```
120
+
111
121
## Grouped Queues
112
122
113
123
Isolated concurrency per key - perfect for per-tenant throttling. Pass `{ group }` as the second argument to `push` or `pushAndWait`.
@@ -151,6 +161,8 @@ const result = await queue.pushAndWait(
151
161
152
162
Throws if the task fails (after retries are exhausted) or if the timeout is reached. Retries are transparent - if the handler fails twice then succeeds on the third attempt, `pushAndWait` resolves with the successful result.
153
163
164
+
Cross-instance delivery is at-least-once. The result is sent over Redis pub/sub for low latency and also written to a short-lived key the waiter reads as a fallback, so a dropped pub/sub message does not turn a completed task into a spurious timeout.
165
+
154
166
## Events
155
167
156
168
```js
@@ -169,7 +181,8 @@ queue.on('drain', () => {})
169
181
payload: any,
170
182
createdAt: number,
171
183
group?: string, // present when pushed with { group }
172
-
attempts: number
184
+
attempts: number,
185
+
signal?: AbortSignal // aborts when the per-task timeout fires
173
186
}
174
187
```
175
188
@@ -277,6 +290,14 @@ Both queue and realtime use the same Redis instance. No key conflicts (`queue:*`
277
290
278
291
Multiple servers can push to the same queue. Redis coordinates via atomic operations - no duplicate processing. Use `globalConcurrency` to enforce a hard limit across all instances.
279
292
293
+
## Startup
294
+
295
+
```js
296
+
awaitqueue.ready()
297
+
```
298
+
299
+
`ready()` resolves once connected. If Redis is unreachable, it rejects after `connectTimeout` (default 10 seconds) instead of hanging, so a process that gates startup on `awaitqueue.ready()` gets a real error to handle. Set `connectTimeout:0` to wait indefinitely. Once connected, the client follows Redis's default reconnect behavior and rides out transient outages.
* @property {number} [cleanupInterval] - ms between empty group cleanup (default 30000, 0 to disable)
17
+
* @property {number|string} [connectTimeout] - max time to wait for a Redis connection before ready() rejects, ms or string like "10s" (default "10s", 0 to wait forever)
17
18
*/
18
19
19
20
/**
@@ -23,18 +24,22 @@ import { semaphore as createSemaphore } from "@prsm/lock"
23
24
* @property {number} createdAt
24
25
* @property {string} [group]
25
26
* @property {number} attempts
27
+
* @property {AbortSignal} [signal] - aborts when the per-task timeout fires
26
28
*/
27
29
28
30
/**
29
31
* @callback TaskHandler
30
32
* @param {any} payload
31
33
* @param {Task} task
34
+
* @param {AbortSignal} signal - aborts when the per-task timeout fires; also available as task.signal
0 commit comments