nuxt-cf-jobs 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/module.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { D1DatabaseLike } from './d1.js';
|
|
2
|
-
import type { DurableJobContinuation, DurableJobRecord, DurableJobRepository, QueuePublisher } from './outbox.js';
|
|
2
|
+
import type { DispatchDurableJobBatchResult, DurableJobContinuation, DurableJobRecord, DurableJobRepository, QueuePublisher } from './outbox.js';
|
|
3
3
|
/** A `job_batches` row as the lifecycle helpers consume it (post-decrement view). */
|
|
4
4
|
export interface DurableBatchRecord {
|
|
5
5
|
id: string;
|
|
@@ -81,11 +81,7 @@ export interface CreateJobBatchOptions<Name extends string = string, Payload ext
|
|
|
81
81
|
export interface CreateJobBatchResult {
|
|
82
82
|
batchId: string;
|
|
83
83
|
jobIds: string[];
|
|
84
|
-
dispatched: Array<
|
|
85
|
-
queue: string;
|
|
86
|
-
dispatched: boolean;
|
|
87
|
-
error?: unknown;
|
|
88
|
-
}>;
|
|
84
|
+
dispatched: Array<DispatchDurableJobBatchResult>;
|
|
89
85
|
}
|
|
90
86
|
/**
|
|
91
87
|
* Atomically register a batch of jobs: insert the `job_batches` row with
|
|
@@ -69,6 +69,14 @@ export interface D1DurableJobRepositoryOptions<Queue extends string = string> {
|
|
|
69
69
|
jobsTable?: string;
|
|
70
70
|
failedJobsTable?: string;
|
|
71
71
|
batchesTable?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Laravel's `retry_after`: when set, `claimJob` also reclaims a reservation
|
|
74
|
+
* older than this many seconds (a dead worker that never acked/released), in
|
|
75
|
+
* one atomic statement — so a redelivered message re-runs instead of bouncing
|
|
76
|
+
* until DLQ. MUST be longer than the slowest job, or a still-running job can be
|
|
77
|
+
* double-claimed. Default unset = only unreserved rows are claimable.
|
|
78
|
+
*/
|
|
79
|
+
reclaimAfterSeconds?: number;
|
|
72
80
|
/** Fire-and-forget hook invoked after a successful claim. Errors are swallowed. */
|
|
73
81
|
onJobClaimed?: (input: {
|
|
74
82
|
job: D1DurableJobRecord<Queue>;
|
|
@@ -88,16 +88,17 @@ export function createD1DurableJobRepository(db, opts = {}) {
|
|
|
88
88
|
},
|
|
89
89
|
async claimJob(id) {
|
|
90
90
|
const now = currentUnixSeconds();
|
|
91
|
+
const reclaimBefore = typeof opts.reclaimAfterSeconds === "number" ? now - opts.reclaimAfterSeconds : -1;
|
|
91
92
|
const job = await db.prepare(`
|
|
92
93
|
UPDATE ${jobsTable}
|
|
93
94
|
SET reserved_at = ?, attempts = attempts + 1
|
|
94
95
|
WHERE id = ?
|
|
95
|
-
AND reserved_at IS NULL
|
|
96
|
+
AND (reserved_at IS NULL OR reserved_at <= ?)
|
|
96
97
|
AND available_at <= ?
|
|
97
98
|
AND completed_at IS NULL
|
|
98
99
|
AND failed_at IS NULL
|
|
99
100
|
RETURNING *
|
|
100
|
-
`).bind(now, id, now).first();
|
|
101
|
+
`).bind(now, id, reclaimBefore, now).first();
|
|
101
102
|
if (job)
|
|
102
103
|
fireHook(() => opts.onJobClaimed?.({ job }));
|
|
103
104
|
return job;
|
|
@@ -200,22 +200,32 @@ export type EnqueueDurableJobResult = {
|
|
|
200
200
|
export declare function enqueueDurableJob<Queue extends string, Record extends DurableJobRecord<Queue>>(repository: Pick<DurableJobRepository<Queue, Record>, 'insertJob'>, publisher: Pick<QueuePublisher<Queue>, 'send'>, record: Record, opts?: {
|
|
201
201
|
delaySeconds?: number;
|
|
202
202
|
}): Promise<EnqueueDurableJobResult>;
|
|
203
|
+
/**
|
|
204
|
+
* Per-queue outcome of a durable batch dispatch, discriminated on `status`:
|
|
205
|
+
* - `sent`: the queue accepted the batch.
|
|
206
|
+
* - `not-dispatched`: the queue binding was missing, so the send was skipped (no
|
|
207
|
+
* throw); the rows are durable and a sweep will redispatch them.
|
|
208
|
+
* - `failed`: the send threw; `cause` is the raw (infra) throw. Also sweep-recoverable.
|
|
209
|
+
*/
|
|
210
|
+
export type DispatchDurableJobBatchResult<Queue extends string = string> = {
|
|
211
|
+
queue: Queue;
|
|
212
|
+
status: 'sent';
|
|
213
|
+
} | {
|
|
214
|
+
queue: Queue;
|
|
215
|
+
status: 'not-dispatched';
|
|
216
|
+
} | {
|
|
217
|
+
queue: Queue;
|
|
218
|
+
status: 'failed';
|
|
219
|
+
cause: unknown;
|
|
220
|
+
};
|
|
203
221
|
export interface SweepDurableJobsResult<Queue extends string> {
|
|
204
222
|
swept: number;
|
|
205
|
-
dispatched: Array<
|
|
206
|
-
queue: Queue;
|
|
207
|
-
dispatched: boolean;
|
|
208
|
-
error?: unknown;
|
|
209
|
-
}>;
|
|
223
|
+
dispatched: Array<DispatchDurableJobBatchResult<Queue>>;
|
|
210
224
|
}
|
|
211
225
|
export declare function sweepDispatchableDurableJobs<Queue extends string>(repository: Pick<DurableJobRecoveryRepository<Queue, Pick<DurableJobRecord<Queue>, 'id' | 'queue'>>, 'findDispatchableJobs'>, publisher: Pick<QueuePublisher<Queue>, 'sendBatch'>, query?: DurableJobRecoveryQuery): Promise<SweepDurableJobsResult<Queue>>;
|
|
212
226
|
export declare function dispatchDurableJobBatch<Queue extends string>(publisher: Pick<QueuePublisher<Queue>, 'sendBatch'>, records: Array<Pick<DurableJobRecord<Queue>, 'id' | 'queue'>>, opts?: {
|
|
213
227
|
delaySeconds?: number;
|
|
214
|
-
}): Promise<Array<
|
|
215
|
-
queue: Queue;
|
|
216
|
-
dispatched: boolean;
|
|
217
|
-
error?: unknown;
|
|
218
|
-
}>>;
|
|
228
|
+
}): Promise<Array<DispatchDurableJobBatchResult<Queue>>>;
|
|
219
229
|
export type DurableJobMessageStatus = 'invalid-message' | DurableJobClaimMiss | 'dispatch-failed' | 'released' | 'failed' | 'completed' | 'errored';
|
|
220
230
|
export interface RunDurableJobMessageOptions<StoredJob, Job extends DispatchableJob, Message extends QueueJobMessage = QueueJobMessage, Env = unknown, Db = unknown, Logger = unknown, CompleteResult = unknown, FailOptions = unknown> {
|
|
221
231
|
message: Pick<QueueMessage<Message>, 'body' | 'ack' | 'retry'>;
|
|
@@ -197,12 +197,10 @@ export async function dispatchDurableJobBatch(publisher, records, opts) {
|
|
|
197
197
|
return await Promise.all(
|
|
198
198
|
[...groups].map(async ([queue, messages]) => {
|
|
199
199
|
try {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
};
|
|
204
|
-
} catch (error) {
|
|
205
|
-
return { queue, dispatched: false, error };
|
|
200
|
+
const sent = await publisher.sendBatch(queue, messages, opts);
|
|
201
|
+
return sent ? { queue, status: "sent" } : { queue, status: "not-dispatched" };
|
|
202
|
+
} catch (cause) {
|
|
203
|
+
return { queue, status: "failed", cause };
|
|
206
204
|
}
|
|
207
205
|
})
|
|
208
206
|
);
|