bunqueue 1.9.6 → 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 +29 -0
- package/dist/application/backgroundTasks.d.ts.map +1 -0
- package/dist/application/backgroundTasks.js +155 -0
- package/dist/application/backgroundTasks.js.map +1 -0
- package/dist/application/cleanupTasks.d.ts +11 -0
- package/dist/application/cleanupTasks.d.ts.map +1 -0
- package/dist/application/cleanupTasks.js +216 -0
- package/dist/application/cleanupTasks.js.map +1 -0
- 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 +15 -0
- package/dist/application/lockManager.d.ts.map +1 -0
- package/dist/application/lockManager.js +118 -0
- package/dist/application/lockManager.js.map +1 -0
- 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 +13 -183
- package/dist/application/queueManager.d.ts.map +1 -1
- package/dist/application/queueManager.js +134 -1110
- 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/application/statsManager.d.ts +56 -0
- package/dist/application/statsManager.d.ts.map +1 -0
- package/dist/application/statsManager.js +111 -0
- package/dist/application/statsManager.js.map +1 -0
- package/dist/application/types.d.ts +123 -0
- package/dist/application/types.d.ts.map +1 -0
- package/dist/application/types.js +16 -0
- package/dist/application/types.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/tcp.d.ts.map +1 -1
- package/dist/infrastructure/server/tcp.js +14 -8
- package/dist/infrastructure/server/tcp.js.map +1 -1
- 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,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Tasks - Periodic maintenance operations
|
|
3
|
+
* Orchestrates stall detection, cleanup, recovery, DLQ maintenance
|
|
4
|
+
*/
|
|
5
|
+
import { processPendingDependencies } from './dependencyProcessor';
|
|
6
|
+
import type { BackgroundContext } from './types';
|
|
7
|
+
import type { CronScheduler } from '../infrastructure/scheduler/cronScheduler';
|
|
8
|
+
/** Background task handles for cleanup */
|
|
9
|
+
export interface BackgroundTaskHandles {
|
|
10
|
+
cleanupInterval: ReturnType<typeof setInterval>;
|
|
11
|
+
timeoutInterval: ReturnType<typeof setInterval>;
|
|
12
|
+
depCheckInterval: ReturnType<typeof setInterval>;
|
|
13
|
+
stallCheckInterval: ReturnType<typeof setInterval>;
|
|
14
|
+
dlqMaintenanceInterval: ReturnType<typeof setInterval>;
|
|
15
|
+
lockCheckInterval: ReturnType<typeof setInterval>;
|
|
16
|
+
cronScheduler: CronScheduler;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Start all background tasks
|
|
20
|
+
* Returns handles that can be used to stop tasks later
|
|
21
|
+
*/
|
|
22
|
+
export declare function startBackgroundTasks(ctx: BackgroundContext, cronScheduler: CronScheduler): BackgroundTaskHandles;
|
|
23
|
+
/**
|
|
24
|
+
* Stop all background tasks
|
|
25
|
+
*/
|
|
26
|
+
export declare function stopBackgroundTasks(handles: BackgroundTaskHandles): void;
|
|
27
|
+
export declare function recover(ctx: BackgroundContext): void;
|
|
28
|
+
export { processPendingDependencies };
|
|
29
|
+
//# sourceMappingURL=backgroundTasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backgroundTasks.d.ts","sourceRoot":"","sources":["../../src/application/backgroundTasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,iBAAiB,EAAe,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAE/E,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAChD,eAAe,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAChD,gBAAgB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACjD,kBAAkB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACnD,sBAAsB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACvD,iBAAiB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IAClD,aAAa,EAAE,aAAa,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,iBAAiB,EACtB,aAAa,EAAE,aAAa,GAC3B,qBAAqB,CA2CvB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAQxE;AA8DD,wBAAgB,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAmCpD;AAGD,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Tasks - Periodic maintenance operations
|
|
3
|
+
* Orchestrates stall detection, cleanup, recovery, DLQ maintenance
|
|
4
|
+
*/
|
|
5
|
+
import { queueLog } from '../shared/logger';
|
|
6
|
+
import { shardIndex } from '../shared/hash';
|
|
7
|
+
import * as dlqOps from './dlqManager';
|
|
8
|
+
import { checkExpiredLocks } from './lockManager';
|
|
9
|
+
import { cleanup } from './cleanupTasks';
|
|
10
|
+
import { checkStalledJobs } from './stallDetection';
|
|
11
|
+
import { processPendingDependencies } from './dependencyProcessor';
|
|
12
|
+
/**
|
|
13
|
+
* Start all background tasks
|
|
14
|
+
* Returns handles that can be used to stop tasks later
|
|
15
|
+
*/
|
|
16
|
+
export function startBackgroundTasks(ctx, cronScheduler) {
|
|
17
|
+
const cleanupInterval = setInterval(() => {
|
|
18
|
+
cleanup(ctx).catch((err) => {
|
|
19
|
+
queueLog.error('Cleanup task failed', { error: String(err) });
|
|
20
|
+
});
|
|
21
|
+
}, ctx.config.cleanupIntervalMs);
|
|
22
|
+
const timeoutInterval = setInterval(() => {
|
|
23
|
+
checkJobTimeouts(ctx);
|
|
24
|
+
}, ctx.config.jobTimeoutCheckMs);
|
|
25
|
+
const depCheckInterval = setInterval(() => {
|
|
26
|
+
processPendingDependencies(ctx).catch((err) => {
|
|
27
|
+
queueLog.error('Dependency check failed', { error: String(err) });
|
|
28
|
+
});
|
|
29
|
+
}, ctx.config.dependencyCheckMs);
|
|
30
|
+
const stallCheckInterval = setInterval(() => {
|
|
31
|
+
checkStalledJobs(ctx);
|
|
32
|
+
}, ctx.config.stallCheckMs);
|
|
33
|
+
const dlqMaintenanceInterval = setInterval(() => {
|
|
34
|
+
performDlqMaintenance(ctx);
|
|
35
|
+
}, ctx.config.dlqMaintenanceMs);
|
|
36
|
+
// Lock expiration check runs at same interval as stall check
|
|
37
|
+
const lockCheckInterval = setInterval(() => {
|
|
38
|
+
checkExpiredLocks(getLockContext(ctx)).catch((err) => {
|
|
39
|
+
queueLog.error('Lock expiration check failed', { error: String(err) });
|
|
40
|
+
});
|
|
41
|
+
}, ctx.config.stallCheckMs);
|
|
42
|
+
cronScheduler.start();
|
|
43
|
+
return {
|
|
44
|
+
cleanupInterval,
|
|
45
|
+
timeoutInterval,
|
|
46
|
+
depCheckInterval,
|
|
47
|
+
stallCheckInterval,
|
|
48
|
+
dlqMaintenanceInterval,
|
|
49
|
+
lockCheckInterval,
|
|
50
|
+
cronScheduler,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stop all background tasks
|
|
55
|
+
*/
|
|
56
|
+
export function stopBackgroundTasks(handles) {
|
|
57
|
+
clearInterval(handles.cleanupInterval);
|
|
58
|
+
clearInterval(handles.timeoutInterval);
|
|
59
|
+
clearInterval(handles.depCheckInterval);
|
|
60
|
+
clearInterval(handles.stallCheckInterval);
|
|
61
|
+
clearInterval(handles.dlqMaintenanceInterval);
|
|
62
|
+
clearInterval(handles.lockCheckInterval);
|
|
63
|
+
handles.cronScheduler.stop();
|
|
64
|
+
}
|
|
65
|
+
/** Extract lock context from background context */
|
|
66
|
+
function getLockContext(ctx) {
|
|
67
|
+
return {
|
|
68
|
+
jobIndex: ctx.jobIndex,
|
|
69
|
+
jobLocks: ctx.jobLocks,
|
|
70
|
+
clientJobs: ctx.clientJobs,
|
|
71
|
+
processingShards: ctx.processingShards,
|
|
72
|
+
processingLocks: ctx.processingLocks,
|
|
73
|
+
shards: ctx.shards,
|
|
74
|
+
shardLocks: ctx.shardLocks,
|
|
75
|
+
eventsManager: ctx.eventsManager,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// ============ Job Timeouts ============
|
|
79
|
+
function checkJobTimeouts(ctx) {
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
for (const procShard of ctx.processingShards) {
|
|
82
|
+
for (const [jobId, job] of procShard) {
|
|
83
|
+
if (job.timeout && job.startedAt && now - job.startedAt > job.timeout) {
|
|
84
|
+
ctx.fail(jobId, 'Job timeout exceeded').catch((err) => {
|
|
85
|
+
queueLog.error('Failed to mark timed out job as failed', {
|
|
86
|
+
jobId: String(jobId),
|
|
87
|
+
error: String(err),
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// ============ DLQ Maintenance ============
|
|
95
|
+
function performDlqMaintenance(ctx) {
|
|
96
|
+
const dlqCtx = {
|
|
97
|
+
shards: ctx.shards,
|
|
98
|
+
jobIndex: ctx.jobIndex,
|
|
99
|
+
storage: ctx.storage,
|
|
100
|
+
};
|
|
101
|
+
for (const queueName of ctx.queueNamesCache) {
|
|
102
|
+
try {
|
|
103
|
+
const retried = dlqOps.processAutoRetry(queueName, dlqCtx);
|
|
104
|
+
if (retried > 0) {
|
|
105
|
+
queueLog.info('DLQ auto-retry completed', { queue: queueName, retried });
|
|
106
|
+
}
|
|
107
|
+
const purged = dlqOps.purgeExpiredDlq(queueName, dlqCtx);
|
|
108
|
+
if (purged > 0) {
|
|
109
|
+
queueLog.info('DLQ purge completed', { queue: queueName, purged });
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
queueLog.error('DLQ maintenance failed', { queue: queueName, error: String(err) });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// ============ Recovery ============
|
|
118
|
+
export function recover(ctx) {
|
|
119
|
+
if (!ctx.storage)
|
|
120
|
+
return;
|
|
121
|
+
const now = Date.now();
|
|
122
|
+
for (const job of ctx.storage.loadPendingJobs()) {
|
|
123
|
+
const idx = shardIndex(job.queue);
|
|
124
|
+
const shard = ctx.shards[idx];
|
|
125
|
+
shard.getQueue(job.queue).push(job);
|
|
126
|
+
ctx.jobIndex.set(job.id, { type: 'queue', shardIdx: idx, queueName: job.queue });
|
|
127
|
+
const isDelayed = job.runAt > now;
|
|
128
|
+
shard.incrementQueued(job.id, isDelayed, job.createdAt, job.queue, job.runAt);
|
|
129
|
+
ctx.registerQueueName(job.queue);
|
|
130
|
+
}
|
|
131
|
+
// Load DLQ entries
|
|
132
|
+
const dlqEntries = ctx.storage.loadDlq();
|
|
133
|
+
let dlqCount = 0;
|
|
134
|
+
for (const [queue, entries] of dlqEntries) {
|
|
135
|
+
const idx = shardIndex(queue);
|
|
136
|
+
const shard = ctx.shards[idx];
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
let dlq = shard.dlq.get(queue);
|
|
139
|
+
if (!dlq) {
|
|
140
|
+
dlq = [];
|
|
141
|
+
shard.dlq.set(queue, dlq);
|
|
142
|
+
}
|
|
143
|
+
dlq.push(entry);
|
|
144
|
+
shard.incrementDlq();
|
|
145
|
+
dlqCount++;
|
|
146
|
+
}
|
|
147
|
+
ctx.registerQueueName(queue);
|
|
148
|
+
}
|
|
149
|
+
if (dlqCount > 0) {
|
|
150
|
+
queueLog.info('Loaded DLQ entries', { count: dlqCount });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Re-export for backward compatibility
|
|
154
|
+
export { processPendingDependencies };
|
|
155
|
+
//# sourceMappingURL=backgroundTasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backgroundTasks.js","sourceRoot":"","sources":["../../src/application/backgroundTasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup Tasks - Periodic maintenance and garbage collection
|
|
3
|
+
* Handles orphaned entries, stale data, and memory management
|
|
4
|
+
*/
|
|
5
|
+
import type { BackgroundContext } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Main cleanup function - called periodically to maintain system health
|
|
8
|
+
* Cleans orphaned entries, stale data, and manages memory
|
|
9
|
+
*/
|
|
10
|
+
export declare function cleanup(ctx: BackgroundContext): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=cleanupTasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanupTasks.d.ts","sourceRoot":"","sources":["../../src/application/cleanupTasks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;GAGG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBnE"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup Tasks - Periodic maintenance and garbage collection
|
|
3
|
+
* Handles orphaned entries, stale data, and memory management
|
|
4
|
+
*/
|
|
5
|
+
import { queueLog } from '../shared/logger';
|
|
6
|
+
import { processingShardIndex, SHARD_COUNT } from '../shared/hash';
|
|
7
|
+
import { withWriteLock } from '../shared/lock';
|
|
8
|
+
/**
|
|
9
|
+
* Main cleanup function - called periodically to maintain system health
|
|
10
|
+
* Cleans orphaned entries, stale data, and manages memory
|
|
11
|
+
*/
|
|
12
|
+
export async function cleanup(ctx) {
|
|
13
|
+
const now = Date.now();
|
|
14
|
+
const stallTimeout = 30 * 60 * 1000; // 30 minutes max for processing
|
|
15
|
+
// Refresh delayed counters
|
|
16
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
17
|
+
ctx.shards[i].refreshDelayedCount(now);
|
|
18
|
+
}
|
|
19
|
+
// Compact priority queues if stale ratio > 20%
|
|
20
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
21
|
+
for (const q of ctx.shards[i].queues.values()) {
|
|
22
|
+
if (q.needsCompaction(0.2)) {
|
|
23
|
+
q.compact();
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
await cleanOrphanedProcessingEntries(ctx, now, stallTimeout);
|
|
28
|
+
cleanStaleWaitingDependencies(ctx, now);
|
|
29
|
+
cleanUniqueKeysAndGroups(ctx);
|
|
30
|
+
cleanStalledCandidates(ctx);
|
|
31
|
+
await cleanOrphanedJobIndex(ctx);
|
|
32
|
+
cleanOrphanedJobLocks(ctx);
|
|
33
|
+
cleanEmptyQueues(ctx);
|
|
34
|
+
}
|
|
35
|
+
async function cleanOrphanedProcessingEntries(ctx, now, stallTimeout) {
|
|
36
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
37
|
+
// Phase 1: Collect candidates (read-only, no lock needed)
|
|
38
|
+
const orphaned = [];
|
|
39
|
+
for (const [jobId, job] of ctx.processingShards[i]) {
|
|
40
|
+
if (job.startedAt && now - job.startedAt > stallTimeout) {
|
|
41
|
+
orphaned.push(jobId);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (orphaned.length === 0)
|
|
45
|
+
continue;
|
|
46
|
+
// Phase 2: Delete with lock to prevent race conditions
|
|
47
|
+
await withWriteLock(ctx.processingLocks[i], () => {
|
|
48
|
+
for (const jobId of orphaned) {
|
|
49
|
+
const job = ctx.processingShards[i].get(jobId);
|
|
50
|
+
if (job) {
|
|
51
|
+
ctx.processingShards[i].delete(jobId);
|
|
52
|
+
ctx.jobIndex.delete(jobId);
|
|
53
|
+
queueLog.warn('Cleaned orphaned processing job', { jobId: String(jobId) });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function cleanStaleWaitingDependencies(ctx, now) {
|
|
60
|
+
const depTimeout = 60 * 60 * 1000; // 1 hour
|
|
61
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
62
|
+
const shard = ctx.shards[i];
|
|
63
|
+
const stale = [];
|
|
64
|
+
for (const [_id, job] of shard.waitingDeps) {
|
|
65
|
+
if (now - job.createdAt > depTimeout) {
|
|
66
|
+
stale.push(job);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const job of stale) {
|
|
70
|
+
shard.waitingDeps.delete(job.id);
|
|
71
|
+
shard.unregisterDependencies(job.id, job.dependsOn);
|
|
72
|
+
ctx.jobIndex.delete(job.id);
|
|
73
|
+
queueLog.warn('Cleaned stale waiting dependency', { jobId: String(job.id) });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function cleanUniqueKeysAndGroups(ctx) {
|
|
78
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
79
|
+
const shard = ctx.shards[i];
|
|
80
|
+
// Clean expired unique keys
|
|
81
|
+
const expiredCleaned = shard.cleanExpiredUniqueKeys();
|
|
82
|
+
if (expiredCleaned > 0) {
|
|
83
|
+
queueLog.info('Cleaned expired unique keys', { shard: i, removed: expiredCleaned });
|
|
84
|
+
}
|
|
85
|
+
// Trim if too many keys remain
|
|
86
|
+
for (const [queueName, keys] of shard.uniqueKeys) {
|
|
87
|
+
if (keys.size > 1000) {
|
|
88
|
+
const toRemove = Math.floor(keys.size / 2);
|
|
89
|
+
const iter = keys.keys();
|
|
90
|
+
for (let j = 0; j < toRemove; j++) {
|
|
91
|
+
const { value, done } = iter.next();
|
|
92
|
+
if (done)
|
|
93
|
+
break;
|
|
94
|
+
keys.delete(value);
|
|
95
|
+
}
|
|
96
|
+
queueLog.info('Trimmed unique keys', { queue: queueName, removed: toRemove });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Clean orphaned active groups
|
|
100
|
+
for (const [queueName, groups] of shard.activeGroups) {
|
|
101
|
+
if (groups.size > 1000) {
|
|
102
|
+
const toRemove = Math.floor(groups.size / 2);
|
|
103
|
+
const iter = groups.values();
|
|
104
|
+
for (let j = 0; j < toRemove; j++) {
|
|
105
|
+
const { value, done } = iter.next();
|
|
106
|
+
if (done)
|
|
107
|
+
break;
|
|
108
|
+
groups.delete(value);
|
|
109
|
+
}
|
|
110
|
+
queueLog.info('Trimmed active groups', { queue: queueName, removed: toRemove });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function cleanStalledCandidates(ctx) {
|
|
116
|
+
for (const jobId of ctx.stalledCandidates) {
|
|
117
|
+
const loc = ctx.jobIndex.get(jobId);
|
|
118
|
+
if (loc?.type !== 'processing') {
|
|
119
|
+
ctx.stalledCandidates.delete(jobId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function cleanOrphanedJobIndex(ctx) {
|
|
124
|
+
// Expensive operation - only run when index is large
|
|
125
|
+
if (ctx.jobIndex.size <= 100_000)
|
|
126
|
+
return;
|
|
127
|
+
// Phase 1: Collect candidates grouped by shard (read-only)
|
|
128
|
+
const processingCandidates = new Map();
|
|
129
|
+
const queueCandidates = new Map();
|
|
130
|
+
for (const [jobId, loc] of ctx.jobIndex) {
|
|
131
|
+
if (loc.type === 'processing') {
|
|
132
|
+
const procIdx = processingShardIndex(String(jobId));
|
|
133
|
+
let list = processingCandidates.get(procIdx);
|
|
134
|
+
if (!list) {
|
|
135
|
+
list = [];
|
|
136
|
+
processingCandidates.set(procIdx, list);
|
|
137
|
+
}
|
|
138
|
+
list.push(jobId);
|
|
139
|
+
}
|
|
140
|
+
else if (loc.type === 'queue') {
|
|
141
|
+
let list = queueCandidates.get(loc.shardIdx);
|
|
142
|
+
if (!list) {
|
|
143
|
+
list = [];
|
|
144
|
+
queueCandidates.set(loc.shardIdx, list);
|
|
145
|
+
}
|
|
146
|
+
list.push({ jobId, queueName: loc.queueName });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
let orphanedCount = 0;
|
|
150
|
+
// Phase 2: Check and delete processing entries with locks
|
|
151
|
+
for (const [procIdx, candidates] of processingCandidates) {
|
|
152
|
+
await withWriteLock(ctx.processingLocks[procIdx], () => {
|
|
153
|
+
for (const jobId of candidates) {
|
|
154
|
+
if (!ctx.processingShards[procIdx].has(jobId)) {
|
|
155
|
+
ctx.jobIndex.delete(jobId);
|
|
156
|
+
orphanedCount++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Phase 3: Check and delete queue entries with locks
|
|
162
|
+
for (const [shardIdx, candidates] of queueCandidates) {
|
|
163
|
+
await withWriteLock(ctx.shardLocks[shardIdx], () => {
|
|
164
|
+
const shard = ctx.shards[shardIdx];
|
|
165
|
+
for (const { jobId, queueName } of candidates) {
|
|
166
|
+
if (!shard.getQueue(queueName).has(jobId)) {
|
|
167
|
+
ctx.jobIndex.delete(jobId);
|
|
168
|
+
orphanedCount++;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (orphanedCount > 0) {
|
|
174
|
+
queueLog.info('Cleaned orphaned jobIndex entries', { count: orphanedCount });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function cleanOrphanedJobLocks(ctx) {
|
|
178
|
+
for (const jobId of ctx.jobLocks.keys()) {
|
|
179
|
+
const loc = ctx.jobIndex.get(jobId);
|
|
180
|
+
if (loc?.type !== 'processing') {
|
|
181
|
+
ctx.jobLocks.delete(jobId);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function cleanEmptyQueues(ctx) {
|
|
186
|
+
for (let i = 0; i < SHARD_COUNT; i++) {
|
|
187
|
+
const shard = ctx.shards[i];
|
|
188
|
+
const emptyQueues = [];
|
|
189
|
+
for (const [queueName, queue] of shard.queues) {
|
|
190
|
+
const dlqEntries = shard.dlq.get(queueName);
|
|
191
|
+
if (queue.size === 0 && (!dlqEntries || dlqEntries.length === 0)) {
|
|
192
|
+
emptyQueues.push(queueName);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const queueName of emptyQueues) {
|
|
196
|
+
shard.queues.delete(queueName);
|
|
197
|
+
shard.dlq.delete(queueName);
|
|
198
|
+
shard.uniqueKeys.delete(queueName);
|
|
199
|
+
shard.queueState.delete(queueName);
|
|
200
|
+
shard.activeGroups.delete(queueName);
|
|
201
|
+
shard.clearQueueLimiters(queueName);
|
|
202
|
+
shard.stallConfig.delete(queueName);
|
|
203
|
+
shard.dlqConfig.delete(queueName);
|
|
204
|
+
ctx.unregisterQueueName(queueName);
|
|
205
|
+
}
|
|
206
|
+
if (emptyQueues.length > 0) {
|
|
207
|
+
queueLog.info('Removed empty queues', { shard: i, count: emptyQueues.length });
|
|
208
|
+
}
|
|
209
|
+
// Clean orphaned temporal index entries
|
|
210
|
+
const cleanedTemporal = shard.cleanOrphanedTemporalEntries();
|
|
211
|
+
if (cleanedTemporal > 0) {
|
|
212
|
+
queueLog.info('Cleaned orphaned temporal entries', { shard: i, count: cleanedTemporal });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=cleanupTasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanupTasks.js","sourceRoot":"","sources":["../../src/application/cleanupTasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Tracking - Client-job relationship management
|
|
3
|
+
* Handles job ownership and release on client disconnect
|
|
4
|
+
*/
|
|
5
|
+
import type { JobId } from '../domain/types/job';
|
|
6
|
+
import type { LockContext } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Register a job as owned by a client (called on PULL).
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerClientJob(clientId: string, jobId: JobId, ctx: LockContext): void;
|
|
11
|
+
/**
|
|
12
|
+
* Unregister a job from a client (called on ACK/FAIL).
|
|
13
|
+
*/
|
|
14
|
+
export declare function unregisterClientJob(clientId: string | undefined, jobId: JobId, ctx: LockContext): void;
|
|
15
|
+
/**
|
|
16
|
+
* Release all jobs owned by a client back to queue (called on TCP disconnect).
|
|
17
|
+
* Returns the number of jobs released.
|
|
18
|
+
*
|
|
19
|
+
* Uses proper locking to prevent race conditions.
|
|
20
|
+
*/
|
|
21
|
+
export declare function releaseClientJobs(clientId: string, ctx: LockContext): Promise<number>;
|
|
22
|
+
//# sourceMappingURL=clientTracking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientTracking.d.ts","sourceRoot":"","sources":["../../src/application/clientTracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAO,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAItD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,CAOxF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,WAAW,GACf,IAAI,CASN;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAuE3F"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Tracking - Client-job relationship management
|
|
3
|
+
* Handles job ownership and release on client disconnect
|
|
4
|
+
*/
|
|
5
|
+
import { queueLog } from '../shared/logger';
|
|
6
|
+
import { shardIndex } from '../shared/hash';
|
|
7
|
+
import { withWriteLock } from '../shared/lock';
|
|
8
|
+
/**
|
|
9
|
+
* Register a job as owned by a client (called on PULL).
|
|
10
|
+
*/
|
|
11
|
+
export function registerClientJob(clientId, jobId, ctx) {
|
|
12
|
+
let jobs = ctx.clientJobs.get(clientId);
|
|
13
|
+
if (!jobs) {
|
|
14
|
+
jobs = new Set();
|
|
15
|
+
ctx.clientJobs.set(clientId, jobs);
|
|
16
|
+
}
|
|
17
|
+
jobs.add(jobId);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Unregister a job from a client (called on ACK/FAIL).
|
|
21
|
+
*/
|
|
22
|
+
export function unregisterClientJob(clientId, jobId, ctx) {
|
|
23
|
+
if (!clientId)
|
|
24
|
+
return;
|
|
25
|
+
const jobs = ctx.clientJobs.get(clientId);
|
|
26
|
+
if (jobs) {
|
|
27
|
+
jobs.delete(jobId);
|
|
28
|
+
if (jobs.size === 0) {
|
|
29
|
+
ctx.clientJobs.delete(clientId);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Release all jobs owned by a client back to queue (called on TCP disconnect).
|
|
35
|
+
* Returns the number of jobs released.
|
|
36
|
+
*
|
|
37
|
+
* Uses proper locking to prevent race conditions.
|
|
38
|
+
*/
|
|
39
|
+
export async function releaseClientJobs(clientId, ctx) {
|
|
40
|
+
const jobs = ctx.clientJobs.get(clientId);
|
|
41
|
+
if (!jobs || jobs.size === 0) {
|
|
42
|
+
ctx.clientJobs.delete(clientId);
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
// Phase 1: Collect jobs to release (read-only, no locks needed)
|
|
46
|
+
const jobsToRelease = [];
|
|
47
|
+
for (const jobId of jobs) {
|
|
48
|
+
const loc = ctx.jobIndex.get(jobId);
|
|
49
|
+
if (loc?.type !== 'processing')
|
|
50
|
+
continue;
|
|
51
|
+
const procIdx = loc.shardIdx;
|
|
52
|
+
const job = ctx.processingShards[procIdx].get(jobId);
|
|
53
|
+
if (!job)
|
|
54
|
+
continue;
|
|
55
|
+
jobsToRelease.push({
|
|
56
|
+
jobId,
|
|
57
|
+
procIdx,
|
|
58
|
+
queueShardIdx: shardIndex(job.queue),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (jobsToRelease.length === 0) {
|
|
62
|
+
ctx.clientJobs.delete(clientId);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
// Phase 2: Group by processing shard for efficient locking
|
|
66
|
+
const byProcShard = new Map();
|
|
67
|
+
for (const item of jobsToRelease) {
|
|
68
|
+
let list = byProcShard.get(item.procIdx);
|
|
69
|
+
if (!list) {
|
|
70
|
+
list = [];
|
|
71
|
+
byProcShard.set(item.procIdx, list);
|
|
72
|
+
}
|
|
73
|
+
list.push(item);
|
|
74
|
+
}
|
|
75
|
+
let released = 0;
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
// Phase 3: Process each processing shard with proper locking
|
|
78
|
+
for (const [procIdx, items] of byProcShard) {
|
|
79
|
+
await withWriteLock(ctx.processingLocks[procIdx], async () => {
|
|
80
|
+
for (const { jobId, queueShardIdx } of items) {
|
|
81
|
+
const job = ctx.processingShards[procIdx].get(jobId);
|
|
82
|
+
if (!job)
|
|
83
|
+
continue;
|
|
84
|
+
// Acquire shard lock for queue modifications
|
|
85
|
+
await withWriteLock(ctx.shardLocks[queueShardIdx], () => {
|
|
86
|
+
released += releaseJobToQueue({ jobId, job, procIdx, queueShardIdx, ctx, now });
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Clear client tracking
|
|
92
|
+
ctx.clientJobs.delete(clientId);
|
|
93
|
+
if (released > 0) {
|
|
94
|
+
queueLog.info('Released client jobs', { clientId: clientId.substring(0, 8), released });
|
|
95
|
+
}
|
|
96
|
+
return released;
|
|
97
|
+
}
|
|
98
|
+
/** Release a single job back to queue */
|
|
99
|
+
function releaseJobToQueue(opts) {
|
|
100
|
+
const { jobId, job, procIdx, queueShardIdx, ctx, now } = opts;
|
|
101
|
+
const shard = ctx.shards[queueShardIdx];
|
|
102
|
+
// Remove from processing
|
|
103
|
+
ctx.processingShards[procIdx].delete(jobId);
|
|
104
|
+
// Release lock if exists
|
|
105
|
+
ctx.jobLocks.delete(jobId);
|
|
106
|
+
// Release concurrency
|
|
107
|
+
shard.releaseConcurrency(job.queue);
|
|
108
|
+
// Release group if active
|
|
109
|
+
if (job.groupId) {
|
|
110
|
+
shard.releaseGroup(job.queue, job.groupId);
|
|
111
|
+
}
|
|
112
|
+
// Reset job state for retry
|
|
113
|
+
job.startedAt = null;
|
|
114
|
+
job.lastHeartbeat = now;
|
|
115
|
+
// Re-queue the job
|
|
116
|
+
shard.getQueue(job.queue).push(job);
|
|
117
|
+
const isDelayed = job.runAt > now;
|
|
118
|
+
shard.incrementQueued(jobId, isDelayed, job.createdAt, job.queue, job.runAt);
|
|
119
|
+
ctx.jobIndex.set(jobId, { type: 'queue', shardIdx: queueShardIdx, queueName: job.queue });
|
|
120
|
+
return 1;
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=clientTracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientTracking.js","sourceRoot":"","sources":["../../src/application/clientTracking.ts"],"names":[],"mappings":"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"}
|