@orchestr-sh/orchestr 1.7.4 → 1.8.0
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/Console/Commands/MakeJobCommand.d.ts +20 -0
- package/dist/Console/Commands/MakeJobCommand.d.ts.map +1 -0
- package/dist/Console/Commands/MakeJobCommand.js +165 -0
- package/dist/Console/Commands/MakeJobCommand.js.map +1 -0
- package/dist/Console/Commands/QueueBatchesTableCommand.d.ts +17 -0
- package/dist/Console/Commands/QueueBatchesTableCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueBatchesTableCommand.js +92 -0
- package/dist/Console/Commands/QueueBatchesTableCommand.js.map +1 -0
- package/dist/Console/Commands/QueueClearCommand.d.ts +16 -0
- package/dist/Console/Commands/QueueClearCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueClearCommand.js +29 -0
- package/dist/Console/Commands/QueueClearCommand.js.map +1 -0
- package/dist/Console/Commands/QueueFailedCommand.d.ts +18 -0
- package/dist/Console/Commands/QueueFailedCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueFailedCommand.js +76 -0
- package/dist/Console/Commands/QueueFailedCommand.js.map +1 -0
- package/dist/Console/Commands/QueueFailedTableCommand.d.ts +17 -0
- package/dist/Console/Commands/QueueFailedTableCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueFailedTableCommand.js +89 -0
- package/dist/Console/Commands/QueueFailedTableCommand.js.map +1 -0
- package/dist/Console/Commands/QueueFlushCommand.d.ts +18 -0
- package/dist/Console/Commands/QueueFlushCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueFlushCommand.js +44 -0
- package/dist/Console/Commands/QueueFlushCommand.js.map +1 -0
- package/dist/Console/Commands/QueueForgetCommand.d.ts +18 -0
- package/dist/Console/Commands/QueueForgetCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueForgetCommand.js +48 -0
- package/dist/Console/Commands/QueueForgetCommand.js.map +1 -0
- package/dist/Console/Commands/QueueMonitorCommand.d.ts +16 -0
- package/dist/Console/Commands/QueueMonitorCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueMonitorCommand.js +42 -0
- package/dist/Console/Commands/QueueMonitorCommand.js.map +1 -0
- package/dist/Console/Commands/QueuePruneBatchesCommand.d.ts +16 -0
- package/dist/Console/Commands/QueuePruneBatchesCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueuePruneBatchesCommand.js +44 -0
- package/dist/Console/Commands/QueuePruneBatchesCommand.js.map +1 -0
- package/dist/Console/Commands/QueuePruneFailedCommand.d.ts +18 -0
- package/dist/Console/Commands/QueuePruneFailedCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueuePruneFailedCommand.js +39 -0
- package/dist/Console/Commands/QueuePruneFailedCommand.js.map +1 -0
- package/dist/Console/Commands/QueueRestartCommand.d.ts +16 -0
- package/dist/Console/Commands/QueueRestartCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueRestartCommand.js +34 -0
- package/dist/Console/Commands/QueueRestartCommand.js.map +1 -0
- package/dist/Console/Commands/QueueRetryCommand.d.ts +20 -0
- package/dist/Console/Commands/QueueRetryCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueRetryCommand.js +77 -0
- package/dist/Console/Commands/QueueRetryCommand.js.map +1 -0
- package/dist/Console/Commands/QueueTableCommand.d.ts +17 -0
- package/dist/Console/Commands/QueueTableCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueTableCommand.js +89 -0
- package/dist/Console/Commands/QueueTableCommand.js.map +1 -0
- package/dist/Console/Commands/QueueWorkCommand.d.ts +16 -0
- package/dist/Console/Commands/QueueWorkCommand.d.ts.map +1 -0
- package/dist/Console/Commands/QueueWorkCommand.js +51 -0
- package/dist/Console/Commands/QueueWorkCommand.js.map +1 -0
- package/dist/Facades/Bus.d.ts +62 -0
- package/dist/Facades/Bus.d.ts.map +1 -0
- package/dist/Facades/Bus.js +102 -0
- package/dist/Facades/Bus.js.map +1 -0
- package/dist/Facades/Queue.d.ts +42 -0
- package/dist/Facades/Queue.d.ts.map +1 -0
- package/dist/Facades/Queue.js +71 -0
- package/dist/Facades/Queue.js.map +1 -0
- package/dist/Facades/index.d.ts +2 -0
- package/dist/Facades/index.d.ts.map +1 -1
- package/dist/Facades/index.js +5 -1
- package/dist/Facades/index.js.map +1 -1
- package/dist/Queue/Batching/Batch.d.ts +86 -0
- package/dist/Queue/Batching/Batch.d.ts.map +1 -0
- package/dist/Queue/Batching/Batch.js +170 -0
- package/dist/Queue/Batching/Batch.js.map +1 -0
- package/dist/Queue/Batching/PendingBatch.d.ts +72 -0
- package/dist/Queue/Batching/PendingBatch.d.ts.map +1 -0
- package/dist/Queue/Batching/PendingBatch.js +122 -0
- package/dist/Queue/Batching/PendingBatch.js.map +1 -0
- package/dist/Queue/Batching/index.d.ts +3 -0
- package/dist/Queue/Batching/index.d.ts.map +1 -0
- package/dist/Queue/Batching/index.js +8 -0
- package/dist/Queue/Batching/index.js.map +1 -0
- package/dist/Queue/Concerns/Dispatchable.d.ts +36 -0
- package/dist/Queue/Concerns/Dispatchable.d.ts.map +1 -0
- package/dist/Queue/Concerns/Dispatchable.js +102 -0
- package/dist/Queue/Concerns/Dispatchable.js.map +1 -0
- package/dist/Queue/Contracts/QueueDriver.d.ts +67 -0
- package/dist/Queue/Contracts/QueueDriver.d.ts.map +1 -0
- package/dist/Queue/Contracts/QueueDriver.js +9 -0
- package/dist/Queue/Contracts/QueueDriver.js.map +1 -0
- package/dist/Queue/Contracts/QueueableJob.d.ts +74 -0
- package/dist/Queue/Contracts/QueueableJob.d.ts.map +1 -0
- package/dist/Queue/Contracts/QueueableJob.js +9 -0
- package/dist/Queue/Contracts/QueueableJob.js.map +1 -0
- package/dist/Queue/Contracts/ShouldBeUnique.d.ts +43 -0
- package/dist/Queue/Contracts/ShouldBeUnique.d.ts.map +1 -0
- package/dist/Queue/Contracts/ShouldBeUnique.js +12 -0
- package/dist/Queue/Contracts/ShouldBeUnique.js.map +1 -0
- package/dist/Queue/Drivers/DatabaseDriver.d.ts +39 -0
- package/dist/Queue/Drivers/DatabaseDriver.d.ts.map +1 -0
- package/dist/Queue/Drivers/DatabaseDriver.js +176 -0
- package/dist/Queue/Drivers/DatabaseDriver.js.map +1 -0
- package/dist/Queue/Drivers/NullDriver.d.ts +30 -0
- package/dist/Queue/Drivers/NullDriver.d.ts.map +1 -0
- package/dist/Queue/Drivers/NullDriver.js +57 -0
- package/dist/Queue/Drivers/NullDriver.js.map +1 -0
- package/dist/Queue/Drivers/SyncDriver.d.ts +29 -0
- package/dist/Queue/Drivers/SyncDriver.d.ts.map +1 -0
- package/dist/Queue/Drivers/SyncDriver.js +67 -0
- package/dist/Queue/Drivers/SyncDriver.js.map +1 -0
- package/dist/Queue/Drivers/index.d.ts +4 -0
- package/dist/Queue/Drivers/index.d.ts.map +1 -0
- package/dist/Queue/Drivers/index.js +10 -0
- package/dist/Queue/Drivers/index.js.map +1 -0
- package/dist/Queue/Events/JobExceptionOccurred.d.ts +13 -0
- package/dist/Queue/Events/JobExceptionOccurred.d.ts.map +1 -0
- package/dist/Queue/Events/JobExceptionOccurred.js +20 -0
- package/dist/Queue/Events/JobExceptionOccurred.js.map +1 -0
- package/dist/Queue/Events/JobFailed.d.ts +13 -0
- package/dist/Queue/Events/JobFailed.d.ts.map +1 -0
- package/dist/Queue/Events/JobFailed.js +20 -0
- package/dist/Queue/Events/JobFailed.js.map +1 -0
- package/dist/Queue/Events/JobProcessed.d.ts +12 -0
- package/dist/Queue/Events/JobProcessed.d.ts.map +1 -0
- package/dist/Queue/Events/JobProcessed.js +18 -0
- package/dist/Queue/Events/JobProcessed.js.map +1 -0
- package/dist/Queue/Events/JobProcessing.d.ts +12 -0
- package/dist/Queue/Events/JobProcessing.d.ts.map +1 -0
- package/dist/Queue/Events/JobProcessing.js +18 -0
- package/dist/Queue/Events/JobProcessing.js.map +1 -0
- package/dist/Queue/Events/JobQueued.d.ts +14 -0
- package/dist/Queue/Events/JobQueued.d.ts.map +1 -0
- package/dist/Queue/Events/JobQueued.js +22 -0
- package/dist/Queue/Events/JobQueued.js.map +1 -0
- package/dist/Queue/Events/JobRetryRequested.d.ts +12 -0
- package/dist/Queue/Events/JobRetryRequested.d.ts.map +1 -0
- package/dist/Queue/Events/JobRetryRequested.js +20 -0
- package/dist/Queue/Events/JobRetryRequested.js.map +1 -0
- package/dist/Queue/Events/WorkerStopping.d.ts +11 -0
- package/dist/Queue/Events/WorkerStopping.d.ts.map +1 -0
- package/dist/Queue/Events/WorkerStopping.js +18 -0
- package/dist/Queue/Events/WorkerStopping.js.map +1 -0
- package/dist/Queue/Events/index.d.ts +8 -0
- package/dist/Queue/Events/index.d.ts.map +1 -0
- package/dist/Queue/Events/index.js +18 -0
- package/dist/Queue/Events/index.js.map +1 -0
- package/dist/Queue/Failed/DatabaseFailedJobProvider.d.ts +33 -0
- package/dist/Queue/Failed/DatabaseFailedJobProvider.d.ts.map +1 -0
- package/dist/Queue/Failed/DatabaseFailedJobProvider.js +100 -0
- package/dist/Queue/Failed/DatabaseFailedJobProvider.js.map +1 -0
- package/dist/Queue/Failed/FailedJobProvider.d.ts +42 -0
- package/dist/Queue/Failed/FailedJobProvider.d.ts.map +1 -0
- package/dist/Queue/Failed/FailedJobProvider.js +9 -0
- package/dist/Queue/Failed/FailedJobProvider.js.map +1 -0
- package/dist/Queue/Job.d.ts +194 -0
- package/dist/Queue/Job.d.ts.map +1 -0
- package/dist/Queue/Job.js +286 -0
- package/dist/Queue/Job.js.map +1 -0
- package/dist/Queue/JobPayload.d.ts +37 -0
- package/dist/Queue/JobPayload.d.ts.map +1 -0
- package/dist/Queue/JobPayload.js +46 -0
- package/dist/Queue/JobPayload.js.map +1 -0
- package/dist/Queue/Middleware/JobMiddleware.d.ts +29 -0
- package/dist/Queue/Middleware/JobMiddleware.d.ts.map +1 -0
- package/dist/Queue/Middleware/JobMiddleware.js +21 -0
- package/dist/Queue/Middleware/JobMiddleware.js.map +1 -0
- package/dist/Queue/Middleware/RateLimited.d.ts +56 -0
- package/dist/Queue/Middleware/RateLimited.d.ts.map +1 -0
- package/dist/Queue/Middleware/RateLimited.js +83 -0
- package/dist/Queue/Middleware/RateLimited.js.map +1 -0
- package/dist/Queue/Middleware/ThrottlesExceptions.d.ts +71 -0
- package/dist/Queue/Middleware/ThrottlesExceptions.d.ts.map +1 -0
- package/dist/Queue/Middleware/ThrottlesExceptions.js +119 -0
- package/dist/Queue/Middleware/ThrottlesExceptions.js.map +1 -0
- package/dist/Queue/Middleware/WithoutOverlapping.d.ts +64 -0
- package/dist/Queue/Middleware/WithoutOverlapping.d.ts.map +1 -0
- package/dist/Queue/Middleware/WithoutOverlapping.js +103 -0
- package/dist/Queue/Middleware/WithoutOverlapping.js.map +1 -0
- package/dist/Queue/Middleware/index.d.ts +5 -0
- package/dist/Queue/Middleware/index.d.ts.map +1 -0
- package/dist/Queue/Middleware/index.js +10 -0
- package/dist/Queue/Middleware/index.js.map +1 -0
- package/dist/Queue/PendingChain.d.ts +63 -0
- package/dist/Queue/PendingChain.d.ts.map +1 -0
- package/dist/Queue/PendingChain.js +111 -0
- package/dist/Queue/PendingChain.js.map +1 -0
- package/dist/Queue/PendingDispatch.d.ts +66 -0
- package/dist/Queue/PendingDispatch.d.ts.map +1 -0
- package/dist/Queue/PendingDispatch.js +101 -0
- package/dist/Queue/PendingDispatch.js.map +1 -0
- package/dist/Queue/QueueManager.d.ts +151 -0
- package/dist/Queue/QueueManager.d.ts.map +1 -0
- package/dist/Queue/QueueManager.js +227 -0
- package/dist/Queue/QueueManager.js.map +1 -0
- package/dist/Queue/QueueServiceProvider.d.ts +19 -0
- package/dist/Queue/QueueServiceProvider.d.ts.map +1 -0
- package/dist/Queue/QueueServiceProvider.js +75 -0
- package/dist/Queue/QueueServiceProvider.js.map +1 -0
- package/dist/Queue/Workers/Worker.d.ts +99 -0
- package/dist/Queue/Workers/Worker.d.ts.map +1 -0
- package/dist/Queue/Workers/Worker.js +324 -0
- package/dist/Queue/Workers/Worker.js.map +1 -0
- package/dist/Queue/Workers/WorkerOptions.d.ts +62 -0
- package/dist/Queue/Workers/WorkerOptions.d.ts.map +1 -0
- package/dist/Queue/Workers/WorkerOptions.js +23 -0
- package/dist/Queue/Workers/WorkerOptions.js.map +1 -0
- package/dist/Queue/index.d.ts +41 -0
- package/dist/Queue/index.d.ts.map +1 -0
- package/dist/Queue/index.js +67 -0
- package/dist/Queue/index.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +92 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ThrottlesExceptions Middleware
|
|
4
|
+
*
|
|
5
|
+
* When a job throws too many exceptions within a given time window,
|
|
6
|
+
* subsequent attempts are delayed to prevent rapid failure loops.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors Laravel's Illuminate\Queue\Middleware\ThrottlesExceptions.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* class ProcessPodcast extends Job {
|
|
13
|
+
* middleware() {
|
|
14
|
+
* return [
|
|
15
|
+
* new ThrottlesExceptions(10, 5) // 10 exceptions per 5 minutes
|
|
16
|
+
* .backoff(5) // Wait 5 minutes before retrying
|
|
17
|
+
* ];
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.ThrottlesExceptions = void 0;
|
|
24
|
+
// In-memory exception tracking
|
|
25
|
+
const exceptionStore = new Map();
|
|
26
|
+
class ThrottlesExceptions {
|
|
27
|
+
maxExceptions;
|
|
28
|
+
decayMinutes;
|
|
29
|
+
/**
|
|
30
|
+
* The number of minutes to back off for
|
|
31
|
+
*/
|
|
32
|
+
backoffMinutes = 5;
|
|
33
|
+
/**
|
|
34
|
+
* The prefix for the throttle key
|
|
35
|
+
*/
|
|
36
|
+
keyPrefix = '';
|
|
37
|
+
/**
|
|
38
|
+
* Whether to retry the job or delete it when throttled
|
|
39
|
+
*/
|
|
40
|
+
shouldRetryOnThrottle = true;
|
|
41
|
+
constructor(
|
|
42
|
+
/**
|
|
43
|
+
* The maximum number of exceptions allowed
|
|
44
|
+
*/
|
|
45
|
+
maxExceptions = 10,
|
|
46
|
+
/**
|
|
47
|
+
* The number of minutes in the decay window
|
|
48
|
+
*/
|
|
49
|
+
decayMinutes = 10) {
|
|
50
|
+
this.maxExceptions = maxExceptions;
|
|
51
|
+
this.decayMinutes = decayMinutes;
|
|
52
|
+
}
|
|
53
|
+
async handle(job, next) {
|
|
54
|
+
const key = this.getKey(job);
|
|
55
|
+
const now = Math.floor(Date.now() / 1000);
|
|
56
|
+
// Clean up expired entries
|
|
57
|
+
const existing = exceptionStore.get(key);
|
|
58
|
+
if (existing && existing.resetAt <= now) {
|
|
59
|
+
exceptionStore.delete(key);
|
|
60
|
+
}
|
|
61
|
+
const current = exceptionStore.get(key);
|
|
62
|
+
// Check if throttled
|
|
63
|
+
if (current && current.count >= this.maxExceptions) {
|
|
64
|
+
if (this.shouldRetryOnThrottle) {
|
|
65
|
+
job.release(this.backoffMinutes * 60);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
job.delete();
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
await next();
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
// Record the exception
|
|
77
|
+
if (current) {
|
|
78
|
+
current.count++;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
exceptionStore.set(key, {
|
|
82
|
+
count: 1,
|
|
83
|
+
resetAt: now + (this.decayMinutes * 60),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get the throttle key for this job
|
|
91
|
+
*/
|
|
92
|
+
getKey(job) {
|
|
93
|
+
const prefix = this.keyPrefix || job.displayName();
|
|
94
|
+
return `throttle:${prefix}`;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Set the number of minutes to back off for when throttled
|
|
98
|
+
*/
|
|
99
|
+
backoff(minutes) {
|
|
100
|
+
this.backoffMinutes = minutes;
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Set a custom key prefix
|
|
105
|
+
*/
|
|
106
|
+
by(key) {
|
|
107
|
+
this.keyPrefix = key;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Indicate the job should NOT be retried when throttled
|
|
112
|
+
*/
|
|
113
|
+
dontRetry() {
|
|
114
|
+
this.shouldRetryOnThrottle = false;
|
|
115
|
+
return this;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
exports.ThrottlesExceptions = ThrottlesExceptions;
|
|
119
|
+
//# sourceMappingURL=ThrottlesExceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThrottlesExceptions.js","sourceRoot":"","sources":["../../../src/Queue/Middleware/ThrottlesExceptions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;AAKH,+BAA+B;AAC/B,MAAM,cAAc,GAAoD,IAAI,GAAG,EAAE,CAAC;AAElF,MAAa,mBAAmB;IAoBlB;IAKA;IAxBZ;;OAEG;IACO,cAAc,GAAW,CAAC,CAAC;IAErC;;OAEG;IACO,SAAS,GAAW,EAAE,CAAC;IAEjC;;OAEG;IACO,qBAAqB,GAAY,IAAI,CAAC;IAEhD;IACE;;OAEG;IACO,gBAAwB,EAAE;IAEpC;;OAEG;IACO,eAAuB,EAAE;QALzB,kBAAa,GAAb,aAAa,CAAa;QAK1B,iBAAY,GAAZ,YAAY,CAAa;IAClC,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,GAAQ,EAAE,IAAyB;QAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAE1C,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,QAAQ,IAAI,QAAQ,CAAC,OAAO,IAAI,GAAG,EAAE,CAAC;YACxC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAExC,qBAAqB;QACrB,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACnD,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uBAAuB;YACvB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE;oBACtB,KAAK,EAAE,CAAC;oBACR,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;iBACxC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACO,MAAM,CAAC,GAAQ;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QACnD,OAAO,YAAY,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,OAAe;QACrB,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,EAAE,CAAC,GAAW;QACZ,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,SAAS;QACP,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAlGD,kDAkGC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WithoutOverlapping Middleware
|
|
3
|
+
*
|
|
4
|
+
* Prevents a job from running if another instance with the same
|
|
5
|
+
* key is currently being processed.
|
|
6
|
+
*
|
|
7
|
+
* Mirrors Laravel's Illuminate\Queue\Middleware\WithoutOverlapping.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* class UpdateSearchIndex extends Job {
|
|
12
|
+
* middleware() {
|
|
13
|
+
* return [new WithoutOverlapping(this.productId)];
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { Job } from '../Job';
|
|
19
|
+
import type { JobMiddleware } from './JobMiddleware';
|
|
20
|
+
export declare class WithoutOverlapping implements JobMiddleware {
|
|
21
|
+
/**
|
|
22
|
+
* The lock key to prevent overlapping
|
|
23
|
+
*/
|
|
24
|
+
protected key: string | number;
|
|
25
|
+
/**
|
|
26
|
+
* The prefix for the lock key
|
|
27
|
+
*/
|
|
28
|
+
protected prefix: string;
|
|
29
|
+
/**
|
|
30
|
+
* The number of seconds to release the job for if locked
|
|
31
|
+
*/
|
|
32
|
+
protected releaseAfterSeconds: number;
|
|
33
|
+
/**
|
|
34
|
+
* The number of seconds the lock should be held
|
|
35
|
+
*/
|
|
36
|
+
protected lockExpiresAfter: number;
|
|
37
|
+
/**
|
|
38
|
+
* Whether to skip the job entirely if locked (vs releasing back to queue)
|
|
39
|
+
*/
|
|
40
|
+
protected shouldDontRelease: boolean;
|
|
41
|
+
constructor(
|
|
42
|
+
/**
|
|
43
|
+
* The lock key to prevent overlapping
|
|
44
|
+
*/
|
|
45
|
+
key: string | number,
|
|
46
|
+
/**
|
|
47
|
+
* The prefix for the lock key
|
|
48
|
+
*/
|
|
49
|
+
prefix?: string);
|
|
50
|
+
handle(job: Job, next: () => Promise<void>): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Set the number of seconds to release the job for if locked
|
|
53
|
+
*/
|
|
54
|
+
releaseAfter(seconds: number): this;
|
|
55
|
+
/**
|
|
56
|
+
* Set the lock expiration time in seconds
|
|
57
|
+
*/
|
|
58
|
+
expireAfter(seconds: number): this;
|
|
59
|
+
/**
|
|
60
|
+
* Indicate the job should be deleted if locked (instead of released)
|
|
61
|
+
*/
|
|
62
|
+
dontRelease(): this;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=WithoutOverlapping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WithoutOverlapping.d.ts","sourceRoot":"","sources":["../../../src/Queue/Middleware/WithoutOverlapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrD,qBAAa,kBAAmB,YAAW,aAAa;IAiBpD;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAE9B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM;IAxB1B;;OAEG;IACH,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAK;IAE1C;;OAEG;IACH,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAK;IAEvC;;OAEG;IACH,SAAS,CAAC,iBAAiB,EAAE,OAAO,CAAS;;IAG3C;;OAEG;IACO,GAAG,EAAE,MAAM,GAAG,MAAM;IAE9B;;OAEG;IACO,MAAM,GAAE,MAAmB;IAGjC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmChE;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKnC;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlC;;OAEG;IACH,WAAW,IAAI,IAAI;CAIpB"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* WithoutOverlapping Middleware
|
|
4
|
+
*
|
|
5
|
+
* Prevents a job from running if another instance with the same
|
|
6
|
+
* key is currently being processed.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors Laravel's Illuminate\Queue\Middleware\WithoutOverlapping.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* class UpdateSearchIndex extends Job {
|
|
13
|
+
* middleware() {
|
|
14
|
+
* return [new WithoutOverlapping(this.productId)];
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.WithoutOverlapping = void 0;
|
|
21
|
+
// Simple in-memory lock store
|
|
22
|
+
const lockStore = new Map();
|
|
23
|
+
class WithoutOverlapping {
|
|
24
|
+
key;
|
|
25
|
+
prefix;
|
|
26
|
+
/**
|
|
27
|
+
* The number of seconds to release the job for if locked
|
|
28
|
+
*/
|
|
29
|
+
releaseAfterSeconds = 0;
|
|
30
|
+
/**
|
|
31
|
+
* The number of seconds the lock should be held
|
|
32
|
+
*/
|
|
33
|
+
lockExpiresAfter = 0;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to skip the job entirely if locked (vs releasing back to queue)
|
|
36
|
+
*/
|
|
37
|
+
shouldDontRelease = false;
|
|
38
|
+
constructor(
|
|
39
|
+
/**
|
|
40
|
+
* The lock key to prevent overlapping
|
|
41
|
+
*/
|
|
42
|
+
key,
|
|
43
|
+
/**
|
|
44
|
+
* The prefix for the lock key
|
|
45
|
+
*/
|
|
46
|
+
prefix = 'overlap:') {
|
|
47
|
+
this.key = key;
|
|
48
|
+
this.prefix = prefix;
|
|
49
|
+
}
|
|
50
|
+
async handle(job, next) {
|
|
51
|
+
const lockKey = `${this.prefix}${this.key}`;
|
|
52
|
+
const now = Math.floor(Date.now() / 1000);
|
|
53
|
+
// Clean up expired locks
|
|
54
|
+
const existing = lockStore.get(lockKey);
|
|
55
|
+
if (existing && existing.expiresAt > 0 && existing.expiresAt <= now) {
|
|
56
|
+
lockStore.delete(lockKey);
|
|
57
|
+
}
|
|
58
|
+
// Check if locked
|
|
59
|
+
if (lockStore.has(lockKey)) {
|
|
60
|
+
if (this.shouldDontRelease) {
|
|
61
|
+
// Skip the job entirely
|
|
62
|
+
job.delete();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
// Release back onto the queue
|
|
66
|
+
job.release(this.releaseAfterSeconds || 5);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Acquire lock
|
|
70
|
+
const expiresAt = this.lockExpiresAfter > 0 ? now + this.lockExpiresAfter : 0;
|
|
71
|
+
lockStore.set(lockKey, { expiresAt });
|
|
72
|
+
try {
|
|
73
|
+
await next();
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
// Release lock
|
|
77
|
+
lockStore.delete(lockKey);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Set the number of seconds to release the job for if locked
|
|
82
|
+
*/
|
|
83
|
+
releaseAfter(seconds) {
|
|
84
|
+
this.releaseAfterSeconds = seconds;
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set the lock expiration time in seconds
|
|
89
|
+
*/
|
|
90
|
+
expireAfter(seconds) {
|
|
91
|
+
this.lockExpiresAfter = seconds;
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Indicate the job should be deleted if locked (instead of released)
|
|
96
|
+
*/
|
|
97
|
+
dontRelease() {
|
|
98
|
+
this.shouldDontRelease = true;
|
|
99
|
+
return this;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.WithoutOverlapping = WithoutOverlapping;
|
|
103
|
+
//# sourceMappingURL=WithoutOverlapping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WithoutOverlapping.js","sourceRoot":"","sources":["../../../src/Queue/Middleware/WithoutOverlapping.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AAKH,8BAA8B;AAC9B,MAAM,SAAS,GAAuC,IAAI,GAAG,EAAE,CAAC;AAEhE,MAAa,kBAAkB;IAoBjB;IAKA;IAxBZ;;OAEG;IACO,mBAAmB,GAAW,CAAC,CAAC;IAE1C;;OAEG;IACO,gBAAgB,GAAW,CAAC,CAAC;IAEvC;;OAEG;IACO,iBAAiB,GAAY,KAAK,CAAC;IAE7C;IACE;;OAEG;IACO,GAAoB;IAE9B;;OAEG;IACO,SAAiB,UAAU;QAL3B,QAAG,GAAH,GAAG,CAAiB;QAKpB,WAAM,GAAN,MAAM,CAAqB;IACpC,CAAC;IAEJ,KAAK,CAAC,MAAM,CAAC,GAAQ,EAAE,IAAyB;QAC9C,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAE1C,yBAAyB;QACzB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,QAAQ,IAAI,QAAQ,CAAC,SAAS,GAAG,CAAC,IAAI,QAAQ,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;YACpE,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,kBAAkB;QAClB,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3B,wBAAwB;gBACxB,GAAG,CAAC,MAAM,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YAED,8BAA8B;YAC9B,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,eAAe;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9E,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAEtC,IAAI,CAAC;YACH,MAAM,IAAI,EAAE,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,eAAe;YACf,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,OAAe;QAC1B,IAAI,CAAC,mBAAmB,GAAG,OAAO,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,OAAe;QACzB,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAtFD,gDAsFC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/Queue/Middleware/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ThrottlesExceptions = exports.WithoutOverlapping = exports.RateLimited = void 0;
|
|
4
|
+
var RateLimited_1 = require("./RateLimited");
|
|
5
|
+
Object.defineProperty(exports, "RateLimited", { enumerable: true, get: function () { return RateLimited_1.RateLimited; } });
|
|
6
|
+
var WithoutOverlapping_1 = require("./WithoutOverlapping");
|
|
7
|
+
Object.defineProperty(exports, "WithoutOverlapping", { enumerable: true, get: function () { return WithoutOverlapping_1.WithoutOverlapping; } });
|
|
8
|
+
var ThrottlesExceptions_1 = require("./ThrottlesExceptions");
|
|
9
|
+
Object.defineProperty(exports, "ThrottlesExceptions", { enumerable: true, get: function () { return ThrottlesExceptions_1.ThrottlesExceptions; } });
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/Queue/Middleware/index.ts"],"names":[],"mappings":";;;AACA,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,2DAA0D;AAAjD,wHAAA,kBAAkB,OAAA;AAC3B,6DAA4D;AAAnD,0HAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PendingChain
|
|
3
|
+
*
|
|
4
|
+
* Fluent builder for chaining multiple jobs together.
|
|
5
|
+
* Jobs in a chain are executed sequentially - if one fails,
|
|
6
|
+
* the remaining jobs in the chain are not executed.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors Laravel's Illuminate\Foundation\Bus\PendingChain.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* await Bus.chain([
|
|
13
|
+
* new ProcessPodcast(id),
|
|
14
|
+
* new OptimizePodcast(id),
|
|
15
|
+
* new ReleasePodcast(id),
|
|
16
|
+
* ])
|
|
17
|
+
* .onConnection('redis')
|
|
18
|
+
* .onQueue('processing')
|
|
19
|
+
* .catch((error) => console.error('Chain failed:', error))
|
|
20
|
+
* .dispatch();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { Job } from './Job';
|
|
24
|
+
import type { QueueManager } from './QueueManager';
|
|
25
|
+
export declare class PendingChain {
|
|
26
|
+
protected manager: QueueManager;
|
|
27
|
+
protected jobs: Job[];
|
|
28
|
+
protected _connection?: string;
|
|
29
|
+
protected _queue?: string;
|
|
30
|
+
protected _delay?: number | Date;
|
|
31
|
+
protected _catchCallback?: (error: Error) => void | Promise<void>;
|
|
32
|
+
protected _finallyCallback?: () => void | Promise<void>;
|
|
33
|
+
constructor(manager: QueueManager, jobs: Job[]);
|
|
34
|
+
/**
|
|
35
|
+
* Set the connection for all jobs in the chain
|
|
36
|
+
*/
|
|
37
|
+
onConnection(connection: string): this;
|
|
38
|
+
/**
|
|
39
|
+
* Set the queue for all jobs in the chain
|
|
40
|
+
*/
|
|
41
|
+
onQueue(queue: string): this;
|
|
42
|
+
/**
|
|
43
|
+
* Set the delay before the first job starts
|
|
44
|
+
*/
|
|
45
|
+
delay(delay: number | Date): this;
|
|
46
|
+
/**
|
|
47
|
+
* Set a callback to execute if any job in the chain fails
|
|
48
|
+
*/
|
|
49
|
+
catch(callback: (error: Error) => void | Promise<void>): this;
|
|
50
|
+
/**
|
|
51
|
+
* Set a callback to execute when the chain completes (success or failure)
|
|
52
|
+
*/
|
|
53
|
+
finally(callback: () => void | Promise<void>): this;
|
|
54
|
+
/**
|
|
55
|
+
* Dispatch the chain
|
|
56
|
+
*
|
|
57
|
+
* The first job is dispatched immediately. Each subsequent job
|
|
58
|
+
* stores the remaining chain and dispatches the next job upon
|
|
59
|
+
* successful completion.
|
|
60
|
+
*/
|
|
61
|
+
dispatch(): Promise<string>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=PendingChain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PendingChain.d.ts","sourceRoot":"","sources":["../../src/Queue/PendingChain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,YAAY;IAQrB,SAAS,CAAC,OAAO,EAAE,YAAY;IAC/B,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE;IARvB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,SAAS,CAAC,gBAAgB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;gBAG5C,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,GAAG,EAAE;IAGvB;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKtC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKjC;;OAEG;IACH,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAK7D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAKnD;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;CAkClC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PendingChain
|
|
4
|
+
*
|
|
5
|
+
* Fluent builder for chaining multiple jobs together.
|
|
6
|
+
* Jobs in a chain are executed sequentially - if one fails,
|
|
7
|
+
* the remaining jobs in the chain are not executed.
|
|
8
|
+
*
|
|
9
|
+
* Mirrors Laravel's Illuminate\Foundation\Bus\PendingChain.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* await Bus.chain([
|
|
14
|
+
* new ProcessPodcast(id),
|
|
15
|
+
* new OptimizePodcast(id),
|
|
16
|
+
* new ReleasePodcast(id),
|
|
17
|
+
* ])
|
|
18
|
+
* .onConnection('redis')
|
|
19
|
+
* .onQueue('processing')
|
|
20
|
+
* .catch((error) => console.error('Chain failed:', error))
|
|
21
|
+
* .dispatch();
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.PendingChain = void 0;
|
|
26
|
+
class PendingChain {
|
|
27
|
+
manager;
|
|
28
|
+
jobs;
|
|
29
|
+
_connection;
|
|
30
|
+
_queue;
|
|
31
|
+
_delay;
|
|
32
|
+
_catchCallback;
|
|
33
|
+
_finallyCallback;
|
|
34
|
+
constructor(manager, jobs) {
|
|
35
|
+
this.manager = manager;
|
|
36
|
+
this.jobs = jobs;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Set the connection for all jobs in the chain
|
|
40
|
+
*/
|
|
41
|
+
onConnection(connection) {
|
|
42
|
+
this._connection = connection;
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Set the queue for all jobs in the chain
|
|
47
|
+
*/
|
|
48
|
+
onQueue(queue) {
|
|
49
|
+
this._queue = queue;
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Set the delay before the first job starts
|
|
54
|
+
*/
|
|
55
|
+
delay(delay) {
|
|
56
|
+
this._delay = delay;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Set a callback to execute if any job in the chain fails
|
|
61
|
+
*/
|
|
62
|
+
catch(callback) {
|
|
63
|
+
this._catchCallback = callback;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Set a callback to execute when the chain completes (success or failure)
|
|
68
|
+
*/
|
|
69
|
+
finally(callback) {
|
|
70
|
+
this._finallyCallback = callback;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Dispatch the chain
|
|
75
|
+
*
|
|
76
|
+
* The first job is dispatched immediately. Each subsequent job
|
|
77
|
+
* stores the remaining chain and dispatches the next job upon
|
|
78
|
+
* successful completion.
|
|
79
|
+
*/
|
|
80
|
+
async dispatch() {
|
|
81
|
+
if (this.jobs.length === 0) {
|
|
82
|
+
throw new Error('Cannot dispatch an empty chain.');
|
|
83
|
+
}
|
|
84
|
+
// Apply connection/queue to all jobs
|
|
85
|
+
for (const job of this.jobs) {
|
|
86
|
+
if (this._connection) {
|
|
87
|
+
job.connection = this._connection;
|
|
88
|
+
}
|
|
89
|
+
if (this._queue) {
|
|
90
|
+
job.queue = this._queue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Store chain metadata on the first job
|
|
94
|
+
const firstJob = this.jobs[0];
|
|
95
|
+
const remainingJobs = this.jobs.slice(1);
|
|
96
|
+
// Store chain info as serializable data
|
|
97
|
+
firstJob._chainJobs = remainingJobs.map((j) => ({
|
|
98
|
+
class: j.constructor.name,
|
|
99
|
+
data: j.toJSON(),
|
|
100
|
+
}));
|
|
101
|
+
firstJob._chainCatch = this._catchCallback;
|
|
102
|
+
firstJob._chainFinally = this._finallyCallback;
|
|
103
|
+
// Apply delay to first job only
|
|
104
|
+
if (this._delay) {
|
|
105
|
+
firstJob.delay = this._delay;
|
|
106
|
+
}
|
|
107
|
+
return this.manager.dispatch(firstJob);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.PendingChain = PendingChain;
|
|
111
|
+
//# sourceMappingURL=PendingChain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PendingChain.js","sourceRoot":"","sources":["../../src/Queue/PendingChain.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;;;AAKH,MAAa,YAAY;IAQX;IACA;IARF,WAAW,CAAU;IACrB,MAAM,CAAU;IAChB,MAAM,CAAiB;IACvB,cAAc,CAA0C;IACxD,gBAAgB,CAA8B;IAExD,YACY,OAAqB,EACrB,IAAW;QADX,YAAO,GAAP,OAAO,CAAc;QACrB,SAAI,GAAJ,IAAI,CAAO;IACpB,CAAC;IAEJ;;OAEG;IACH,YAAY,CAAC,UAAkB;QAC7B,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,KAAa;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAoB;QACxB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAgD;QACpD,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,QAAoC;QAC1C,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,qCAAqC;QACrC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;YACpC,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEzC,wCAAwC;QACvC,QAAgB,CAAC,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC,IAAI;YACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;SACjB,CAAC,CAAC,CAAC;QACH,QAAgB,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC;QACnD,QAAgB,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAExD,gCAAgC;QAChC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC/B,CAAC;QAED,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACF;AA7FD,oCA6FC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PendingDispatch
|
|
3
|
+
*
|
|
4
|
+
* Provides a fluent interface for configuring job dispatch.
|
|
5
|
+
* Mirrors Laravel's Illuminate\Foundation\Bus\PendingDispatch.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* await ProcessPodcast.dispatch(podcastId)
|
|
10
|
+
* .onConnection('redis')
|
|
11
|
+
* .onQueue('processing')
|
|
12
|
+
* .delay(60);
|
|
13
|
+
*
|
|
14
|
+
* // The dispatch happens when the PendingDispatch is awaited
|
|
15
|
+
* // or when .dispatch() is explicitly called
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
import type { Job } from './Job';
|
|
19
|
+
import type { QueueManager } from './QueueManager';
|
|
20
|
+
export declare class PendingDispatch implements PromiseLike<string> {
|
|
21
|
+
protected manager: QueueManager;
|
|
22
|
+
protected job: Job;
|
|
23
|
+
protected _afterCommit: boolean;
|
|
24
|
+
constructor(manager: QueueManager, job: Job);
|
|
25
|
+
/**
|
|
26
|
+
* Set the desired connection for the job
|
|
27
|
+
*/
|
|
28
|
+
onConnection(connection: string): this;
|
|
29
|
+
/**
|
|
30
|
+
* Set the desired queue for the job
|
|
31
|
+
*/
|
|
32
|
+
onQueue(queue: string): this;
|
|
33
|
+
/**
|
|
34
|
+
* Set the delay for the job
|
|
35
|
+
*/
|
|
36
|
+
delay(delay: number | Date): this;
|
|
37
|
+
/**
|
|
38
|
+
* Set the number of times the job may be attempted
|
|
39
|
+
*/
|
|
40
|
+
tries(tries: number): this;
|
|
41
|
+
/**
|
|
42
|
+
* Set the timeout for the job
|
|
43
|
+
*/
|
|
44
|
+
timeout(timeout: number): this;
|
|
45
|
+
/**
|
|
46
|
+
* Set the backoff strategy for the job
|
|
47
|
+
*/
|
|
48
|
+
backoff(backoff: number | number[]): this;
|
|
49
|
+
/**
|
|
50
|
+
* Indicate that the job should be dispatched after all DB transactions commit
|
|
51
|
+
*/
|
|
52
|
+
afterCommit(): this;
|
|
53
|
+
/**
|
|
54
|
+
* Indicate that the job should not wait for DB transactions
|
|
55
|
+
*/
|
|
56
|
+
beforeCommit(): this;
|
|
57
|
+
/**
|
|
58
|
+
* Dispatch the job to the queue
|
|
59
|
+
*/
|
|
60
|
+
dispatch(): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* PromiseLike implementation - allows `await ProcessPodcast.dispatch(id)`
|
|
63
|
+
*/
|
|
64
|
+
then<TResult1 = string, TResult2 = never>(onfulfilled?: ((value: string) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=PendingDispatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PendingDispatch.d.ts","sourceRoot":"","sources":["../../src/Queue/PendingDispatch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,eAAgB,YAAW,WAAW,CAAC,MAAM,CAAC;IAIvD,SAAS,CAAC,OAAO,EAAE,YAAY;IAC/B,SAAS,CAAC,GAAG,EAAE,GAAG;IAJpB,SAAS,CAAC,YAAY,EAAE,OAAO,CAAS;gBAG5B,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,GAAG;IAGpB;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKtC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK5B;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKjC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK1B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK9B;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAKzC;;OAEG;IACH,WAAW,IAAI,IAAI;IAMnB;;OAEG;IACH,YAAY,IAAI,IAAI;IAMpB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC;;OAEG;IACH,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,QAAQ,GAAG,KAAK,EACtC,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,EAC1E,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GACtE,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAC;CAGpC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PendingDispatch
|
|
4
|
+
*
|
|
5
|
+
* Provides a fluent interface for configuring job dispatch.
|
|
6
|
+
* Mirrors Laravel's Illuminate\Foundation\Bus\PendingDispatch.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* await ProcessPodcast.dispatch(podcastId)
|
|
11
|
+
* .onConnection('redis')
|
|
12
|
+
* .onQueue('processing')
|
|
13
|
+
* .delay(60);
|
|
14
|
+
*
|
|
15
|
+
* // The dispatch happens when the PendingDispatch is awaited
|
|
16
|
+
* // or when .dispatch() is explicitly called
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.PendingDispatch = void 0;
|
|
21
|
+
class PendingDispatch {
|
|
22
|
+
manager;
|
|
23
|
+
job;
|
|
24
|
+
_afterCommit = false;
|
|
25
|
+
constructor(manager, job) {
|
|
26
|
+
this.manager = manager;
|
|
27
|
+
this.job = job;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Set the desired connection for the job
|
|
31
|
+
*/
|
|
32
|
+
onConnection(connection) {
|
|
33
|
+
this.job.connection = connection;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set the desired queue for the job
|
|
38
|
+
*/
|
|
39
|
+
onQueue(queue) {
|
|
40
|
+
this.job.queue = queue;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Set the delay for the job
|
|
45
|
+
*/
|
|
46
|
+
delay(delay) {
|
|
47
|
+
this.job.delay = delay;
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Set the number of times the job may be attempted
|
|
52
|
+
*/
|
|
53
|
+
tries(tries) {
|
|
54
|
+
this.job.tries = tries;
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Set the timeout for the job
|
|
59
|
+
*/
|
|
60
|
+
timeout(timeout) {
|
|
61
|
+
this.job.timeout = timeout;
|
|
62
|
+
return this;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Set the backoff strategy for the job
|
|
66
|
+
*/
|
|
67
|
+
backoff(backoff) {
|
|
68
|
+
this.job.backoff = backoff;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Indicate that the job should be dispatched after all DB transactions commit
|
|
73
|
+
*/
|
|
74
|
+
afterCommit() {
|
|
75
|
+
this._afterCommit = true;
|
|
76
|
+
this.job.afterCommit = true;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Indicate that the job should not wait for DB transactions
|
|
81
|
+
*/
|
|
82
|
+
beforeCommit() {
|
|
83
|
+
this._afterCommit = false;
|
|
84
|
+
this.job.afterCommit = false;
|
|
85
|
+
return this;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Dispatch the job to the queue
|
|
89
|
+
*/
|
|
90
|
+
async dispatch() {
|
|
91
|
+
return this.manager.dispatch(this.job);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* PromiseLike implementation - allows `await ProcessPodcast.dispatch(id)`
|
|
95
|
+
*/
|
|
96
|
+
then(onfulfilled, onrejected) {
|
|
97
|
+
return this.dispatch().then(onfulfilled, onrejected);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.PendingDispatch = PendingDispatch;
|
|
101
|
+
//# sourceMappingURL=PendingDispatch.js.map
|