bunqueue 1.9.7 → 1.9.8
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/application/backgroundTasks.d.ts +3 -6
- package/dist/application/backgroundTasks.d.ts.map +1 -1
- package/dist/application/backgroundTasks.js +9 -172
- package/dist/application/backgroundTasks.js.map +1 -1
- package/dist/application/cleanupTasks.d.ts +1 -1
- package/dist/application/cleanupTasks.d.ts.map +1 -1
- package/dist/application/cleanupTasks.js +57 -22
- package/dist/application/cleanupTasks.js.map +1 -1
- package/dist/application/clientTracking.d.ts +22 -0
- package/dist/application/clientTracking.d.ts.map +1 -0
- package/dist/application/clientTracking.js +122 -0
- package/dist/application/clientTracking.js.map +1 -0
- package/dist/application/contextFactory.d.ts +97 -0
- package/dist/application/contextFactory.d.ts.map +1 -0
- package/dist/application/contextFactory.js +169 -0
- package/dist/application/contextFactory.js.map +1 -0
- package/dist/application/dependencyProcessor.d.ts +11 -0
- package/dist/application/dependencyProcessor.d.ts.map +1 -0
- package/dist/application/dependencyProcessor.js +69 -0
- package/dist/application/dependencyProcessor.js.map +1 -0
- package/dist/application/dlqManager.d.ts +12 -0
- package/dist/application/dlqManager.d.ts.map +1 -1
- package/dist/application/dlqManager.js +36 -0
- package/dist/application/dlqManager.js.map +1 -1
- package/dist/application/lockManager.d.ts +2 -49
- package/dist/application/lockManager.d.ts.map +1 -1
- package/dist/application/lockManager.js +73 -262
- package/dist/application/lockManager.js.map +1 -1
- package/dist/application/lockOperations.d.ts +39 -0
- package/dist/application/lockOperations.d.ts.map +1 -0
- package/dist/application/lockOperations.js +101 -0
- package/dist/application/lockOperations.js.map +1 -0
- package/dist/application/operations/ack.d.ts +0 -5
- package/dist/application/operations/ack.d.ts.map +1 -1
- package/dist/application/operations/ack.js +30 -258
- package/dist/application/operations/ack.js.map +1 -1
- package/dist/application/operations/ackHelpers.d.ts +78 -0
- package/dist/application/operations/ackHelpers.d.ts.map +1 -0
- package/dist/application/operations/ackHelpers.js +162 -0
- package/dist/application/operations/ackHelpers.js.map +1 -0
- package/dist/application/operations/jobManagement.d.ts +2 -0
- package/dist/application/operations/jobManagement.d.ts.map +1 -1
- package/dist/application/operations/jobManagement.js +8 -0
- package/dist/application/operations/jobManagement.js.map +1 -1
- package/dist/application/operations/push.d.ts.map +1 -1
- package/dist/application/operations/push.js +8 -2
- package/dist/application/operations/push.js.map +1 -1
- package/dist/application/operations/queryOperations.d.ts +11 -0
- package/dist/application/operations/queryOperations.d.ts.map +1 -1
- package/dist/application/operations/queryOperations.js +32 -0
- package/dist/application/operations/queryOperations.js.map +1 -1
- package/dist/application/queueManager.d.ts +3 -11
- package/dist/application/queueManager.d.ts.map +1 -1
- package/dist/application/queueManager.js +90 -243
- package/dist/application/queueManager.js.map +1 -1
- package/dist/application/stallDetection.d.ts +11 -0
- package/dist/application/stallDetection.d.ts.map +1 -0
- package/dist/application/stallDetection.js +128 -0
- package/dist/application/stallDetection.js.map +1 -0
- package/dist/domain/queue/dependencyTracker.d.ts +74 -0
- package/dist/domain/queue/dependencyTracker.d.ts.map +1 -0
- package/dist/domain/queue/dependencyTracker.js +126 -0
- package/dist/domain/queue/dependencyTracker.js.map +1 -0
- package/dist/domain/queue/dlqShard.d.ts +59 -0
- package/dist/domain/queue/dlqShard.d.ts.map +1 -0
- package/dist/domain/queue/dlqShard.js +165 -0
- package/dist/domain/queue/dlqShard.js.map +1 -0
- package/dist/domain/queue/limiterManager.d.ts +44 -0
- package/dist/domain/queue/limiterManager.d.ts.map +1 -0
- package/dist/domain/queue/limiterManager.js +99 -0
- package/dist/domain/queue/limiterManager.js.map +1 -0
- package/dist/domain/queue/shard.d.ts +29 -122
- package/dist/domain/queue/shard.d.ts.map +1 -1
- package/dist/domain/queue/shard.js +152 -426
- package/dist/domain/queue/shard.js.map +1 -1
- package/dist/domain/queue/temporalManager.d.ts +81 -0
- package/dist/domain/queue/temporalManager.d.ts.map +1 -0
- package/dist/domain/queue/temporalManager.js +149 -0
- package/dist/domain/queue/temporalManager.js.map +1 -0
- package/dist/domain/queue/uniqueKeyManager.d.ts +32 -0
- package/dist/domain/queue/uniqueKeyManager.d.ts.map +1 -0
- package/dist/domain/queue/uniqueKeyManager.js +87 -0
- package/dist/domain/queue/uniqueKeyManager.js.map +1 -0
- package/dist/infrastructure/backup/s3Backup.d.ts +3 -40
- package/dist/infrastructure/backup/s3Backup.d.ts.map +1 -1
- package/dist/infrastructure/backup/s3Backup.js +10 -182
- package/dist/infrastructure/backup/s3Backup.js.map +1 -1
- package/dist/infrastructure/backup/s3BackupConfig.d.ts +67 -0
- package/dist/infrastructure/backup/s3BackupConfig.d.ts.map +1 -0
- package/dist/infrastructure/backup/s3BackupConfig.js +48 -0
- package/dist/infrastructure/backup/s3BackupConfig.js.map +1 -0
- package/dist/infrastructure/backup/s3BackupOperations.d.ts +23 -0
- package/dist/infrastructure/backup/s3BackupOperations.d.ts.map +1 -0
- package/dist/infrastructure/backup/s3BackupOperations.js +170 -0
- package/dist/infrastructure/backup/s3BackupOperations.js.map +1 -0
- package/dist/infrastructure/persistence/sqlite.d.ts +4 -13
- package/dist/infrastructure/persistence/sqlite.d.ts.map +1 -1
- package/dist/infrastructure/persistence/sqlite.js +23 -178
- package/dist/infrastructure/persistence/sqlite.js.map +1 -1
- package/dist/infrastructure/persistence/sqliteBatch.d.ts +38 -0
- package/dist/infrastructure/persistence/sqliteBatch.d.ts.map +1 -0
- package/dist/infrastructure/persistence/sqliteBatch.js +124 -0
- package/dist/infrastructure/persistence/sqliteBatch.js.map +1 -0
- package/dist/infrastructure/persistence/sqliteSerializer.d.ts +17 -0
- package/dist/infrastructure/persistence/sqliteSerializer.d.ts.map +1 -0
- package/dist/infrastructure/persistence/sqliteSerializer.js +81 -0
- package/dist/infrastructure/persistence/sqliteSerializer.js.map +1 -0
- package/dist/infrastructure/server/handler.d.ts.map +1 -1
- package/dist/infrastructure/server/handler.js +1 -186
- package/dist/infrastructure/server/handler.js.map +1 -1
- package/dist/infrastructure/server/handlerRoutes.d.ts +23 -0
- package/dist/infrastructure/server/handlerRoutes.d.ts.map +1 -0
- package/dist/infrastructure/server/handlerRoutes.js +190 -0
- package/dist/infrastructure/server/handlerRoutes.js.map +1 -0
- package/dist/infrastructure/server/http.d.ts +4 -25
- package/dist/infrastructure/server/http.d.ts.map +1 -1
- package/dist/infrastructure/server/http.js +43 -285
- package/dist/infrastructure/server/http.js.map +1 -1
- package/dist/infrastructure/server/httpEndpoints.d.ts +19 -0
- package/dist/infrastructure/server/httpEndpoints.d.ts.map +1 -0
- package/dist/infrastructure/server/httpEndpoints.js +151 -0
- package/dist/infrastructure/server/httpEndpoints.js.map +1 -0
- package/dist/infrastructure/server/sseHandler.d.ts +27 -0
- package/dist/infrastructure/server/sseHandler.d.ts.map +1 -0
- package/dist/infrastructure/server/sseHandler.js +77 -0
- package/dist/infrastructure/server/sseHandler.js.map +1 -0
- package/dist/infrastructure/server/wsHandler.d.ts +31 -0
- package/dist/infrastructure/server/wsHandler.d.ts.map +1 -0
- package/dist/infrastructure/server/wsHandler.js +63 -0
- package/dist/infrastructure/server/wsHandler.js.map +1 -0
- package/dist/mcp/index.js +3 -465
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/mcpHandlers.d.ts +129 -0
- package/dist/mcp/mcpHandlers.d.ts.map +1 -0
- package/dist/mcp/mcpHandlers.js +204 -0
- package/dist/mcp/mcpHandlers.js.map +1 -0
- package/dist/mcp/mcpTools.d.ts +15 -0
- package/dist/mcp/mcpTools.d.ts.map +1 -0
- package/dist/mcp/mcpTools.js +277 -0
- package/dist/mcp/mcpTools.js.map +1 -0
- package/package.json +2 -2
- package/dist/cli/dashboard.d.ts +0 -32
- package/dist/cli/dashboard.d.ts.map +0 -1
- package/dist/cli/dashboard.js +0 -183
- package/dist/cli/dashboard.js.map +0 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stall Detection - Job stall detection and recovery
|
|
3
|
+
* Uses two-phase detection (like BullMQ) to prevent false positives
|
|
4
|
+
*/
|
|
5
|
+
import type { BackgroundContext } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Check for stalled jobs and handle them
|
|
8
|
+
* Uses two-phase detection to prevent false positives
|
|
9
|
+
*/
|
|
10
|
+
export declare function checkStalledJobs(ctx: BackgroundContext): void;
|
|
11
|
+
//# sourceMappingURL=stallDetection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stallDetection.d.ts","sourceRoot":"","sources":["../../src/application/stallDetection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAoD7D"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stall Detection - Job stall detection and recovery
|
|
3
|
+
* Uses two-phase detection (like BullMQ) to prevent false positives
|
|
4
|
+
*/
|
|
5
|
+
import { calculateBackoff } from '../domain/types/job';
|
|
6
|
+
import { getStallAction, incrementStallCount } from '../domain/types/stall';
|
|
7
|
+
import { queueLog } from '../shared/logger';
|
|
8
|
+
import { shardIndex, processingShardIndex, SHARD_COUNT } from '../shared/hash';
|
|
9
|
+
import { withWriteLock } from '../shared/lock';
|
|
10
|
+
/**
|
|
11
|
+
* Check for stalled jobs and handle them
|
|
12
|
+
* Uses two-phase detection to prevent false positives
|
|
13
|
+
*/
|
|
14
|
+
export function checkStalledJobs(ctx) {
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const confirmedStalled = [];
|
|
17
|
+
// Phase 1: Check jobs that were candidates from previous cycle
|
|
18
|
+
for (const jobId of ctx.stalledCandidates) {
|
|
19
|
+
const procIdx = processingShardIndex(String(jobId));
|
|
20
|
+
const job = ctx.processingShards[procIdx].get(jobId);
|
|
21
|
+
if (!job) {
|
|
22
|
+
ctx.stalledCandidates.delete(jobId);
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const stallConfig = ctx.shards[shardIndex(job.queue)].getStallConfig(job.queue);
|
|
26
|
+
if (!stallConfig.enabled) {
|
|
27
|
+
ctx.stalledCandidates.delete(jobId);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
const action = getStallAction(job, stallConfig, now);
|
|
31
|
+
if (action !== "keep" /* StallAction.Keep */) {
|
|
32
|
+
confirmedStalled.push({ job, action });
|
|
33
|
+
}
|
|
34
|
+
ctx.stalledCandidates.delete(jobId);
|
|
35
|
+
}
|
|
36
|
+
// Phase 2: Mark current processing jobs as candidates for NEXT check
|
|
37
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
38
|
+
const procShard = ctx.processingShards[i];
|
|
39
|
+
for (const [jobId, job] of procShard) {
|
|
40
|
+
const stallConfig = ctx.shards[shardIndex(job.queue)].getStallConfig(job.queue);
|
|
41
|
+
if (!stallConfig.enabled)
|
|
42
|
+
continue;
|
|
43
|
+
const action = getStallAction(job, stallConfig, now);
|
|
44
|
+
if (action !== "keep" /* StallAction.Keep */) {
|
|
45
|
+
ctx.stalledCandidates.add(jobId);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Process confirmed stalled jobs
|
|
50
|
+
for (const { job, action } of confirmedStalled) {
|
|
51
|
+
handleStalledJob(job, action, ctx).catch((err) => {
|
|
52
|
+
queueLog.error('Failed to handle stalled job', {
|
|
53
|
+
jobId: String(job.id),
|
|
54
|
+
error: String(err),
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Handle a stalled job based on the action
|
|
61
|
+
* Uses proper locking to prevent race conditions
|
|
62
|
+
*/
|
|
63
|
+
async function handleStalledJob(job, action, ctx) {
|
|
64
|
+
const idx = shardIndex(job.queue);
|
|
65
|
+
const procIdx = processingShardIndex(String(job.id));
|
|
66
|
+
// Broadcast events before acquiring locks (non-blocking)
|
|
67
|
+
ctx.eventsManager.broadcast({
|
|
68
|
+
eventType: "stalled" /* EventType.Stalled */,
|
|
69
|
+
queue: job.queue,
|
|
70
|
+
jobId: job.id,
|
|
71
|
+
timestamp: Date.now(),
|
|
72
|
+
data: { stallCount: job.stallCount + 1, action },
|
|
73
|
+
});
|
|
74
|
+
void ctx.webhookManager.trigger('stalled', String(job.id), job.queue, {
|
|
75
|
+
data: { stallCount: job.stallCount + 1, action },
|
|
76
|
+
});
|
|
77
|
+
// Acquire processing lock first, then shard lock
|
|
78
|
+
await withWriteLock(ctx.processingLocks[procIdx], async () => {
|
|
79
|
+
// Verify job is still in processing (might have been handled already)
|
|
80
|
+
if (!ctx.processingShards[procIdx].has(job.id)) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
await withWriteLock(ctx.shardLocks[idx], () => {
|
|
84
|
+
const shard = ctx.shards[idx];
|
|
85
|
+
if (action === "move_to_dlq" /* StallAction.MoveToDlq */) {
|
|
86
|
+
moveStalliedJobToDlq(job, ctx, shard, procIdx, idx);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
retryStalliedJob(job, ctx, shard, procIdx, idx);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** Move stalled job to DLQ */
|
|
95
|
+
function moveStalliedJobToDlq(job, ctx, shard, procIdx, _idx) {
|
|
96
|
+
queueLog.warn('Job exceeded max stalls, moving to DLQ', {
|
|
97
|
+
jobId: String(job.id),
|
|
98
|
+
queue: job.queue,
|
|
99
|
+
stallCount: job.stallCount,
|
|
100
|
+
});
|
|
101
|
+
ctx.processingShards[procIdx].delete(job.id);
|
|
102
|
+
shard.releaseConcurrency(job.queue);
|
|
103
|
+
const entry = shard.addToDlq(job, "stalled" /* FailureReason.Stalled */, `Job stalled ${job.stallCount + 1} times`);
|
|
104
|
+
ctx.jobIndex.set(job.id, { type: 'dlq', queueName: job.queue });
|
|
105
|
+
ctx.storage?.saveDlqEntry(entry);
|
|
106
|
+
}
|
|
107
|
+
/** Retry stalled job */
|
|
108
|
+
function retryStalliedJob(job, ctx, shard, procIdx, idx) {
|
|
109
|
+
incrementStallCount(job);
|
|
110
|
+
job.attempts++;
|
|
111
|
+
job.startedAt = null;
|
|
112
|
+
job.runAt = Date.now() + calculateBackoff(job);
|
|
113
|
+
job.lastHeartbeat = Date.now();
|
|
114
|
+
queueLog.warn('Job stalled, retrying', {
|
|
115
|
+
jobId: String(job.id),
|
|
116
|
+
queue: job.queue,
|
|
117
|
+
stallCount: job.stallCount,
|
|
118
|
+
attempt: job.attempts,
|
|
119
|
+
});
|
|
120
|
+
ctx.processingShards[procIdx].delete(job.id);
|
|
121
|
+
shard.releaseConcurrency(job.queue);
|
|
122
|
+
shard.getQueue(job.queue).push(job);
|
|
123
|
+
const isDelayed = job.runAt > Date.now();
|
|
124
|
+
shard.incrementQueued(job.id, isDelayed, job.createdAt, job.queue, job.runAt);
|
|
125
|
+
ctx.jobIndex.set(job.id, { type: 'queue', shardIdx: idx, queueName: job.queue });
|
|
126
|
+
ctx.storage?.updateForRetry(job);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=stallDetection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stallDetection.js","sourceRoot":"","sources":["../../src/application/stallDetection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAe,cAAc,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAGzF,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAsB;IACrD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,gBAAgB,GAA6C,EAAE,CAAC;IAEtE,+DAA+D;IAC/D,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,iBAAiB,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAErD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAChF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACrD,IAAI,MAAM,kCAAqB,EAAE,CAAC;YAChC,gBAAgB,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,GAAG,CAAC,iBAAiB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IAED,qEAAqE;IACrE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAE1C,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,SAAS,EAAE,CAAC;YACrC,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChF,IAAI,CAAC,WAAW,CAAC,OAAO;gBAAE,SAAS;YAEnC,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;YACrD,IAAI,MAAM,kCAAqB,EAAE,CAAC;gBAChC,GAAG,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,KAAK,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,gBAAgB,EAAE,CAAC;QAC/C,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;YACxD,QAAQ,CAAC,KAAK,CAAC,8BAA8B,EAAE;gBAC7C,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;aACnB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,gBAAgB,CAC7B,GAAQ,EACR,MAAmB,EACnB,GAAsB;IAEtB,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAErD,yDAAyD;IACzD,GAAG,CAAC,aAAa,CAAC,SAAS,CAAC;QAC1B,SAAS,mCAAmB;QAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,KAAK,EAAE,GAAG,CAAC,EAAE;QACb,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,MAAM,EAAE;KACjD,CAAC,CAAC;IACH,KAAK,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,SAAyB,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE;QACpF,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE,MAAM,EAAE;KACjD,CAAC,CAAC;IAEH,iDAAiD;IACjD,MAAM,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,IAAI,EAAE;QAC3D,sEAAsE;QACtE,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/C,OAAO;QACT,CAAC;QAED,MAAM,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE;YAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAE9B,IAAI,MAAM,8CAA0B,EAAE,CAAC;gBACrC,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,8BAA8B;AAC9B,SAAS,oBAAoB,CAC3B,GAAQ,EACR,GAAsB,EACtB,KAA0C,EAC1C,OAAe,EACf,IAAY;IAEZ,QAAQ,CAAC,IAAI,CAAC,wCAAwC,EAAE;QACtD,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;KAC3B,CAAC,CAAC;IAEH,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7C,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAC1B,GAAG,yCAEH,eAAe,GAAG,CAAC,UAAU,GAAG,CAAC,QAAQ,CAC1C,CAAC;IACF,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IAChE,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,wBAAwB;AACxB,SAAS,gBAAgB,CACvB,GAAQ,EACR,GAAsB,EACtB,KAA0C,EAC1C,OAAe,EACf,GAAW;IAEX,mBAAmB,CAAC,GAAG,CAAC,CAAC;IACzB,GAAG,CAAC,QAAQ,EAAE,CAAC;IACf,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC;IACrB,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC/C,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE/B,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE;QACrC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,OAAO,EAAE,GAAG,CAAC,QAAQ;KACtB,CAAC,CAAC;IAEH,GAAG,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7C,KAAK,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEpC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9E,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACjF,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DependencyTracker - Tracks job dependencies and parent-child relationships
|
|
3
|
+
*/
|
|
4
|
+
import type { Job, JobId } from '../types/job';
|
|
5
|
+
/**
|
|
6
|
+
* Manages job dependency tracking for a shard
|
|
7
|
+
* Provides O(1) lookup when dependencies complete
|
|
8
|
+
*/
|
|
9
|
+
export declare class DependencyTracker {
|
|
10
|
+
/** Jobs waiting for dependencies */
|
|
11
|
+
readonly waitingDeps: Map<JobId, Job>;
|
|
12
|
+
/**
|
|
13
|
+
* Reverse index: depId -> Set of jobIds waiting for that dependency
|
|
14
|
+
* Enables O(1) lookup when a dependency completes instead of O(n) scan
|
|
15
|
+
*/
|
|
16
|
+
readonly dependencyIndex: Map<JobId, Set<JobId>>;
|
|
17
|
+
/** Parent jobs waiting for children to complete */
|
|
18
|
+
readonly waitingChildren: Map<JobId, Job>;
|
|
19
|
+
/**
|
|
20
|
+
* Register a job's dependencies in the reverse index
|
|
21
|
+
* Call when adding a job to waitingDeps
|
|
22
|
+
*/
|
|
23
|
+
registerDependencies(jobId: JobId, dependsOn: JobId[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* Unregister a job's dependencies from the reverse index
|
|
26
|
+
* Call when removing a job from waitingDeps
|
|
27
|
+
*/
|
|
28
|
+
unregisterDependencies(jobId: JobId, dependsOn: JobId[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get jobs waiting for a specific dependency - O(1)
|
|
31
|
+
*/
|
|
32
|
+
getJobsWaitingFor(depId: JobId): Set<JobId> | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Add a job that is waiting for dependencies
|
|
35
|
+
*/
|
|
36
|
+
addWaitingJob(job: Job): void;
|
|
37
|
+
/**
|
|
38
|
+
* Remove a job from waiting deps
|
|
39
|
+
*/
|
|
40
|
+
removeWaitingJob(jobId: JobId): Job | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Get a job waiting for dependencies
|
|
43
|
+
*/
|
|
44
|
+
getWaitingJob(jobId: JobId): Job | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Check if a job is waiting for dependencies
|
|
47
|
+
*/
|
|
48
|
+
isWaiting(jobId: JobId): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Add a parent job waiting for children
|
|
51
|
+
*/
|
|
52
|
+
addWaitingParent(job: Job): void;
|
|
53
|
+
/**
|
|
54
|
+
* Remove a parent job from waiting
|
|
55
|
+
*/
|
|
56
|
+
removeWaitingParent(jobId: JobId): Job | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Get a parent job waiting for children
|
|
59
|
+
*/
|
|
60
|
+
getWaitingParent(jobId: JobId): Job | undefined;
|
|
61
|
+
/**
|
|
62
|
+
* Check if a parent is waiting for children
|
|
63
|
+
*/
|
|
64
|
+
isParentWaiting(jobId: JobId): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Get counts for debugging
|
|
67
|
+
*/
|
|
68
|
+
getCounts(): {
|
|
69
|
+
waitingDeps: number;
|
|
70
|
+
dependencyIndex: number;
|
|
71
|
+
waitingChildren: number;
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=dependencyTracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencyTracker.d.ts","sourceRoot":"","sources":["../../../src/domain/queue/dependencyTracker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE/C;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,WAAW,kBAAyB;IAE7C;;;OAGG;IACH,QAAQ,CAAC,eAAe,yBAAgC;IAExD,mDAAmD;IACnD,QAAQ,CAAC,eAAe,kBAAyB;IAEjD;;;OAGG;IACH,oBAAoB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI;IAW5D;;;OAGG;IACH,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI;IAY9D;;OAEG;IACH,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,SAAS;IAIvD;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAO7B;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS;IAW/C;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS;IAI5C;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAIhC;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAIhC;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS;IAQlD;;OAEG;IACH,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,GAAG,GAAG,SAAS;IAI/C;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAItC;;OAEG;IACH,SAAS,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE;CAOvF"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DependencyTracker - Tracks job dependencies and parent-child relationships
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Manages job dependency tracking for a shard
|
|
6
|
+
* Provides O(1) lookup when dependencies complete
|
|
7
|
+
*/
|
|
8
|
+
export class DependencyTracker {
|
|
9
|
+
/** Jobs waiting for dependencies */
|
|
10
|
+
waitingDeps = new Map();
|
|
11
|
+
/**
|
|
12
|
+
* Reverse index: depId -> Set of jobIds waiting for that dependency
|
|
13
|
+
* Enables O(1) lookup when a dependency completes instead of O(n) scan
|
|
14
|
+
*/
|
|
15
|
+
dependencyIndex = new Map();
|
|
16
|
+
/** Parent jobs waiting for children to complete */
|
|
17
|
+
waitingChildren = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Register a job's dependencies in the reverse index
|
|
20
|
+
* Call when adding a job to waitingDeps
|
|
21
|
+
*/
|
|
22
|
+
registerDependencies(jobId, dependsOn) {
|
|
23
|
+
for (const depId of dependsOn) {
|
|
24
|
+
let waiters = this.dependencyIndex.get(depId);
|
|
25
|
+
if (!waiters) {
|
|
26
|
+
waiters = new Set();
|
|
27
|
+
this.dependencyIndex.set(depId, waiters);
|
|
28
|
+
}
|
|
29
|
+
waiters.add(jobId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Unregister a job's dependencies from the reverse index
|
|
34
|
+
* Call when removing a job from waitingDeps
|
|
35
|
+
*/
|
|
36
|
+
unregisterDependencies(jobId, dependsOn) {
|
|
37
|
+
for (const depId of dependsOn) {
|
|
38
|
+
const waiters = this.dependencyIndex.get(depId);
|
|
39
|
+
if (waiters) {
|
|
40
|
+
waiters.delete(jobId);
|
|
41
|
+
if (waiters.size === 0) {
|
|
42
|
+
this.dependencyIndex.delete(depId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get jobs waiting for a specific dependency - O(1)
|
|
49
|
+
*/
|
|
50
|
+
getJobsWaitingFor(depId) {
|
|
51
|
+
return this.dependencyIndex.get(depId);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Add a job that is waiting for dependencies
|
|
55
|
+
*/
|
|
56
|
+
addWaitingJob(job) {
|
|
57
|
+
this.waitingDeps.set(job.id, job);
|
|
58
|
+
if (job.dependsOn && job.dependsOn.length > 0) {
|
|
59
|
+
this.registerDependencies(job.id, job.dependsOn);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Remove a job from waiting deps
|
|
64
|
+
*/
|
|
65
|
+
removeWaitingJob(jobId) {
|
|
66
|
+
const job = this.waitingDeps.get(jobId);
|
|
67
|
+
if (job) {
|
|
68
|
+
this.waitingDeps.delete(jobId);
|
|
69
|
+
if (job.dependsOn && job.dependsOn.length > 0) {
|
|
70
|
+
this.unregisterDependencies(jobId, job.dependsOn);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return job;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get a job waiting for dependencies
|
|
77
|
+
*/
|
|
78
|
+
getWaitingJob(jobId) {
|
|
79
|
+
return this.waitingDeps.get(jobId);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Check if a job is waiting for dependencies
|
|
83
|
+
*/
|
|
84
|
+
isWaiting(jobId) {
|
|
85
|
+
return this.waitingDeps.has(jobId);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Add a parent job waiting for children
|
|
89
|
+
*/
|
|
90
|
+
addWaitingParent(job) {
|
|
91
|
+
this.waitingChildren.set(job.id, job);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove a parent job from waiting
|
|
95
|
+
*/
|
|
96
|
+
removeWaitingParent(jobId) {
|
|
97
|
+
const job = this.waitingChildren.get(jobId);
|
|
98
|
+
if (job) {
|
|
99
|
+
this.waitingChildren.delete(jobId);
|
|
100
|
+
}
|
|
101
|
+
return job;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get a parent job waiting for children
|
|
105
|
+
*/
|
|
106
|
+
getWaitingParent(jobId) {
|
|
107
|
+
return this.waitingChildren.get(jobId);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if a parent is waiting for children
|
|
111
|
+
*/
|
|
112
|
+
isParentWaiting(jobId) {
|
|
113
|
+
return this.waitingChildren.has(jobId);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get counts for debugging
|
|
117
|
+
*/
|
|
118
|
+
getCounts() {
|
|
119
|
+
return {
|
|
120
|
+
waitingDeps: this.waitingDeps.size,
|
|
121
|
+
dependencyIndex: this.dependencyIndex.size,
|
|
122
|
+
waitingChildren: this.waitingChildren.size,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=dependencyTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencyTracker.js","sourceRoot":"","sources":["../../../src/domain/queue/dependencyTracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DlqShard - Dead Letter Queue operations for a shard
|
|
3
|
+
*/
|
|
4
|
+
import type { Job, JobId } from '../types/job';
|
|
5
|
+
import type { DlqEntry, DlqConfig, DlqFilter } from '../types/dlq';
|
|
6
|
+
import { FailureReason } from '../types/dlq';
|
|
7
|
+
import type { StallConfig } from '../types/stall';
|
|
8
|
+
/** Stats callback for counter updates */
|
|
9
|
+
export interface DlqStatsCallback {
|
|
10
|
+
incrementDlq(): void;
|
|
11
|
+
decrementDlq(count?: number): void;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Manages Dead Letter Queue operations for a shard
|
|
15
|
+
*/
|
|
16
|
+
export declare class DlqShard {
|
|
17
|
+
/** Dead letter queue by queue name */
|
|
18
|
+
private readonly dlq;
|
|
19
|
+
/** DLQ configuration per queue */
|
|
20
|
+
private readonly dlqConfig;
|
|
21
|
+
/** Stall configuration per queue */
|
|
22
|
+
private readonly stallConfig;
|
|
23
|
+
/** Stats callback for counter updates */
|
|
24
|
+
private readonly stats;
|
|
25
|
+
constructor(stats: DlqStatsCallback);
|
|
26
|
+
/** Get DLQ config for queue */
|
|
27
|
+
getConfig(queue: string): DlqConfig;
|
|
28
|
+
/** Set DLQ config for queue */
|
|
29
|
+
setConfig(queue: string, config: Partial<DlqConfig>): void;
|
|
30
|
+
/** Get stall config for queue */
|
|
31
|
+
getStallConfig(queue: string): StallConfig;
|
|
32
|
+
/** Set stall config for queue */
|
|
33
|
+
setStallConfig(queue: string, config: Partial<StallConfig>): void;
|
|
34
|
+
/** Add job to DLQ with full metadata */
|
|
35
|
+
add(job: Job, reason?: FailureReason, error?: string | null): DlqEntry;
|
|
36
|
+
/** Get DLQ entries (raw) */
|
|
37
|
+
getEntries(queue: string): DlqEntry[];
|
|
38
|
+
/** Get DLQ jobs (for backward compatibility) */
|
|
39
|
+
getJobs(queue: string, count?: number): Job[];
|
|
40
|
+
/** Get DLQ entries with filter */
|
|
41
|
+
getFiltered(queue: string, filter: DlqFilter): DlqEntry[];
|
|
42
|
+
/** Remove entry from DLQ by job ID */
|
|
43
|
+
remove(queue: string, jobId: JobId): DlqEntry | null;
|
|
44
|
+
/** Get entries ready for auto-retry */
|
|
45
|
+
getAutoRetryEntries(queue: string, now?: number): DlqEntry[];
|
|
46
|
+
/** Get expired entries for cleanup */
|
|
47
|
+
getExpiredEntries(queue: string, now?: number): DlqEntry[];
|
|
48
|
+
/** Remove expired entries */
|
|
49
|
+
purgeExpired(queue: string, now?: number): number;
|
|
50
|
+
/** Clear DLQ for queue */
|
|
51
|
+
clear(queue: string): number;
|
|
52
|
+
/** Get DLQ count for queue */
|
|
53
|
+
getCount(queue: string): number;
|
|
54
|
+
/** Get all queue names with DLQ entries */
|
|
55
|
+
getQueueNames(): string[];
|
|
56
|
+
/** Delete queue data */
|
|
57
|
+
deleteQueue(queue: string): number;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=dlqShard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlqShard.d.ts","sourceRoot":"","sources":["../../../src/domain/queue/dlqShard.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACnE,OAAO,EAEL,aAAa,EAId,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,yCAAyC;AACzC,MAAM,WAAW,gBAAgB;IAC/B,YAAY,IAAI,IAAI,CAAC;IACrB,YAAY,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,qBAAa,QAAQ;IACnB,sCAAsC;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAiC;IAErD,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAE1D,oCAAoC;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAE9D,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;gBAE7B,KAAK,EAAE,gBAAgB;IAInC,+BAA+B;IAC/B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAInC,+BAA+B;IAC/B,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAK1D,iCAAiC;IACjC,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW;IAI1C,iCAAiC;IACjC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAKjE,wCAAwC;IACxC,GAAG,CACD,GAAG,EAAE,GAAG,EACR,MAAM,GAAE,aAAqC,EAC7C,KAAK,GAAE,MAAM,GAAG,IAAW,GAC1B,QAAQ;IAqBX,4BAA4B;IAC5B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE;IAIrC,gDAAgD;IAChD,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,GAAG,EAAE;IAO7C,kCAAkC;IAClC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,QAAQ,EAAE;IAwBzD,sCAAsC;IACtC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,IAAI;IASpD,uCAAuC;IACvC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,QAAQ,EAAE;IAOxE,sCAAsC;IACtC,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,QAAQ,EAAE;IAMtE,6BAA6B;IAC7B,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM;IAgB7D,0BAA0B;IAC1B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAS5B,8BAA8B;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI/B,2CAA2C;IAC3C,aAAa,IAAI,MAAM,EAAE;IAIzB,wBAAwB;IACxB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAQnC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DlqShard - Dead Letter Queue operations for a shard
|
|
3
|
+
*/
|
|
4
|
+
import { DEFAULT_DLQ_CONFIG, createDlqEntry, isDlqEntryExpired, canAutoRetry, } from '../types/dlq';
|
|
5
|
+
import { DEFAULT_STALL_CONFIG } from '../types/stall';
|
|
6
|
+
/**
|
|
7
|
+
* Manages Dead Letter Queue operations for a shard
|
|
8
|
+
*/
|
|
9
|
+
export class DlqShard {
|
|
10
|
+
/** Dead letter queue by queue name */
|
|
11
|
+
dlq = new Map();
|
|
12
|
+
/** DLQ configuration per queue */
|
|
13
|
+
dlqConfig = new Map();
|
|
14
|
+
/** Stall configuration per queue */
|
|
15
|
+
stallConfig = new Map();
|
|
16
|
+
/** Stats callback for counter updates */
|
|
17
|
+
stats;
|
|
18
|
+
constructor(stats) {
|
|
19
|
+
this.stats = stats;
|
|
20
|
+
}
|
|
21
|
+
/** Get DLQ config for queue */
|
|
22
|
+
getConfig(queue) {
|
|
23
|
+
return this.dlqConfig.get(queue) ?? DEFAULT_DLQ_CONFIG;
|
|
24
|
+
}
|
|
25
|
+
/** Set DLQ config for queue */
|
|
26
|
+
setConfig(queue, config) {
|
|
27
|
+
const current = this.getConfig(queue);
|
|
28
|
+
this.dlqConfig.set(queue, { ...current, ...config });
|
|
29
|
+
}
|
|
30
|
+
/** Get stall config for queue */
|
|
31
|
+
getStallConfig(queue) {
|
|
32
|
+
return this.stallConfig.get(queue) ?? DEFAULT_STALL_CONFIG;
|
|
33
|
+
}
|
|
34
|
+
/** Set stall config for queue */
|
|
35
|
+
setStallConfig(queue, config) {
|
|
36
|
+
const current = this.getStallConfig(queue);
|
|
37
|
+
this.stallConfig.set(queue, { ...current, ...config });
|
|
38
|
+
}
|
|
39
|
+
/** Add job to DLQ with full metadata */
|
|
40
|
+
add(job, reason = "unknown" /* FailureReason.Unknown */, error = null) {
|
|
41
|
+
let entries = this.dlq.get(job.queue);
|
|
42
|
+
if (!entries) {
|
|
43
|
+
entries = [];
|
|
44
|
+
this.dlq.set(job.queue, entries);
|
|
45
|
+
}
|
|
46
|
+
const config = this.getConfig(job.queue);
|
|
47
|
+
const entry = createDlqEntry(job, reason, error, config);
|
|
48
|
+
// Enforce max entries
|
|
49
|
+
while (entries.length >= config.maxEntries) {
|
|
50
|
+
entries.shift(); // Remove oldest
|
|
51
|
+
this.stats.decrementDlq();
|
|
52
|
+
}
|
|
53
|
+
entries.push(entry);
|
|
54
|
+
this.stats.incrementDlq();
|
|
55
|
+
return entry;
|
|
56
|
+
}
|
|
57
|
+
/** Get DLQ entries (raw) */
|
|
58
|
+
getEntries(queue) {
|
|
59
|
+
return this.dlq.get(queue) ?? [];
|
|
60
|
+
}
|
|
61
|
+
/** Get DLQ jobs (for backward compatibility) */
|
|
62
|
+
getJobs(queue, count) {
|
|
63
|
+
const entries = this.dlq.get(queue);
|
|
64
|
+
if (!entries)
|
|
65
|
+
return [];
|
|
66
|
+
const slice = count ? entries.slice(0, count) : entries;
|
|
67
|
+
return slice.map((e) => e.job);
|
|
68
|
+
}
|
|
69
|
+
/** Get DLQ entries with filter */
|
|
70
|
+
getFiltered(queue, filter) {
|
|
71
|
+
const entries = this.dlq.get(queue);
|
|
72
|
+
if (!entries)
|
|
73
|
+
return [];
|
|
74
|
+
const now = Date.now();
|
|
75
|
+
let result = entries.filter((entry) => {
|
|
76
|
+
if (filter.reason && entry.reason !== filter.reason)
|
|
77
|
+
return false;
|
|
78
|
+
if (filter.olderThan && entry.enteredAt >= filter.olderThan)
|
|
79
|
+
return false;
|
|
80
|
+
if (filter.newerThan && entry.enteredAt <= filter.newerThan)
|
|
81
|
+
return false;
|
|
82
|
+
if (filter.retriable && !canAutoRetry(entry, this.getConfig(queue), now))
|
|
83
|
+
return false;
|
|
84
|
+
if (filter.expired && !isDlqEntryExpired(entry, now))
|
|
85
|
+
return false;
|
|
86
|
+
return true;
|
|
87
|
+
});
|
|
88
|
+
if (filter.offset) {
|
|
89
|
+
result = result.slice(filter.offset);
|
|
90
|
+
}
|
|
91
|
+
if (filter.limit) {
|
|
92
|
+
result = result.slice(0, filter.limit);
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
/** Remove entry from DLQ by job ID */
|
|
97
|
+
remove(queue, jobId) {
|
|
98
|
+
const entries = this.dlq.get(queue);
|
|
99
|
+
if (!entries)
|
|
100
|
+
return null;
|
|
101
|
+
const idx = entries.findIndex((e) => e.job.id === jobId);
|
|
102
|
+
if (idx === -1)
|
|
103
|
+
return null;
|
|
104
|
+
this.stats.decrementDlq();
|
|
105
|
+
return entries.splice(idx, 1)[0];
|
|
106
|
+
}
|
|
107
|
+
/** Get entries ready for auto-retry */
|
|
108
|
+
getAutoRetryEntries(queue, now = Date.now()) {
|
|
109
|
+
const entries = this.dlq.get(queue);
|
|
110
|
+
if (!entries)
|
|
111
|
+
return [];
|
|
112
|
+
const config = this.getConfig(queue);
|
|
113
|
+
return entries.filter((entry) => canAutoRetry(entry, config, now));
|
|
114
|
+
}
|
|
115
|
+
/** Get expired entries for cleanup */
|
|
116
|
+
getExpiredEntries(queue, now = Date.now()) {
|
|
117
|
+
const entries = this.dlq.get(queue);
|
|
118
|
+
if (!entries)
|
|
119
|
+
return [];
|
|
120
|
+
return entries.filter((entry) => isDlqEntryExpired(entry, now));
|
|
121
|
+
}
|
|
122
|
+
/** Remove expired entries */
|
|
123
|
+
purgeExpired(queue, now = Date.now()) {
|
|
124
|
+
const entries = this.dlq.get(queue);
|
|
125
|
+
if (!entries)
|
|
126
|
+
return 0;
|
|
127
|
+
const before = entries.length;
|
|
128
|
+
const remaining = entries.filter((entry) => !isDlqEntryExpired(entry, now));
|
|
129
|
+
if (remaining.length < before) {
|
|
130
|
+
this.dlq.set(queue, remaining);
|
|
131
|
+
const removed = before - remaining.length;
|
|
132
|
+
this.stats.decrementDlq(removed);
|
|
133
|
+
return removed;
|
|
134
|
+
}
|
|
135
|
+
return 0;
|
|
136
|
+
}
|
|
137
|
+
/** Clear DLQ for queue */
|
|
138
|
+
clear(queue) {
|
|
139
|
+
const entries = this.dlq.get(queue);
|
|
140
|
+
if (!entries)
|
|
141
|
+
return 0;
|
|
142
|
+
const count = entries.length;
|
|
143
|
+
this.dlq.delete(queue);
|
|
144
|
+
this.stats.decrementDlq(count);
|
|
145
|
+
return count;
|
|
146
|
+
}
|
|
147
|
+
/** Get DLQ count for queue */
|
|
148
|
+
getCount(queue) {
|
|
149
|
+
return this.dlq.get(queue)?.length ?? 0;
|
|
150
|
+
}
|
|
151
|
+
/** Get all queue names with DLQ entries */
|
|
152
|
+
getQueueNames() {
|
|
153
|
+
return Array.from(this.dlq.keys());
|
|
154
|
+
}
|
|
155
|
+
/** Delete queue data */
|
|
156
|
+
deleteQueue(queue) {
|
|
157
|
+
const entries = this.dlq.get(queue);
|
|
158
|
+
const count = entries?.length ?? 0;
|
|
159
|
+
this.dlq.delete(queue);
|
|
160
|
+
this.dlqConfig.delete(queue);
|
|
161
|
+
this.stallConfig.delete(queue);
|
|
162
|
+
return count;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=dlqShard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dlqShard.js","sourceRoot":"","sources":["../../../src/domain/queue/dlqShard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LimiterManager - Rate limiting and concurrency control
|
|
3
|
+
*/
|
|
4
|
+
import { type QueueState } from '../types/queue';
|
|
5
|
+
/**
|
|
6
|
+
* Manages rate limiting and concurrency for queues
|
|
7
|
+
*/
|
|
8
|
+
export declare class LimiterManager {
|
|
9
|
+
/** Queue state (pause, rate limit, concurrency) */
|
|
10
|
+
private readonly queueState;
|
|
11
|
+
/** Rate limiters per queue */
|
|
12
|
+
private readonly rateLimiters;
|
|
13
|
+
/** Concurrency limiters per queue */
|
|
14
|
+
private readonly concurrencyLimiters;
|
|
15
|
+
/** Get queue state */
|
|
16
|
+
getState(name: string): QueueState;
|
|
17
|
+
/** Check if queue is paused */
|
|
18
|
+
isPaused(name: string): boolean;
|
|
19
|
+
/** Pause queue */
|
|
20
|
+
pause(name: string): void;
|
|
21
|
+
/** Resume queue */
|
|
22
|
+
resume(name: string): void;
|
|
23
|
+
/** Set rate limit for queue */
|
|
24
|
+
setRateLimit(queue: string, limit: number): void;
|
|
25
|
+
/** Clear rate limit */
|
|
26
|
+
clearRateLimit(queue: string): void;
|
|
27
|
+
/** Try to acquire rate limit token */
|
|
28
|
+
tryAcquireRateLimit(queue: string): boolean;
|
|
29
|
+
/** Set concurrency limit for queue */
|
|
30
|
+
setConcurrency(queue: string, limit: number): void;
|
|
31
|
+
/** Clear concurrency limit */
|
|
32
|
+
clearConcurrency(queue: string): void;
|
|
33
|
+
/** Try to acquire concurrency slot */
|
|
34
|
+
tryAcquireConcurrency(queue: string): boolean;
|
|
35
|
+
/** Release concurrency slot */
|
|
36
|
+
releaseConcurrency(queue: string): void;
|
|
37
|
+
/** Get all queue names with state */
|
|
38
|
+
getQueueNames(): string[];
|
|
39
|
+
/** Delete queue data */
|
|
40
|
+
deleteQueue(queue: string): void;
|
|
41
|
+
/** Get the underlying state map (for backward compatibility) */
|
|
42
|
+
getStateMap(): Map<string, QueueState>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=limiterManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"limiterManager.d.ts","sourceRoot":"","sources":["../../../src/domain/queue/limiterManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,UAAU,EAAqD,MAAM,gBAAgB,CAAC;AAEpG;;GAEG;AACH,qBAAa,cAAc;IACzB,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;IAE5D,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAE/D,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAyC;IAE7E,sBAAsB;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU;IASlC,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI/B,kBAAkB;IAClB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB,mBAAmB;IACnB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM1B,+BAA+B;IAC/B,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKhD,uBAAuB;IACvB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMnC,sCAAsC;IACtC,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAO3C,sCAAsC;IACtC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAWlD,8BAA8B;IAC9B,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMrC,sCAAsC;IACtC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAK7C,+BAA+B;IAC/B,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMvC,qCAAqC;IACrC,aAAa,IAAI,MAAM,EAAE;IAIzB,wBAAwB;IACxB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAMhC,gEAAgE;IAChE,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC;CAGvC"}
|