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.
Files changed (156) hide show
  1. package/dist/application/backgroundTasks.d.ts +29 -0
  2. package/dist/application/backgroundTasks.d.ts.map +1 -0
  3. package/dist/application/backgroundTasks.js +155 -0
  4. package/dist/application/backgroundTasks.js.map +1 -0
  5. package/dist/application/cleanupTasks.d.ts +11 -0
  6. package/dist/application/cleanupTasks.d.ts.map +1 -0
  7. package/dist/application/cleanupTasks.js +216 -0
  8. package/dist/application/cleanupTasks.js.map +1 -0
  9. package/dist/application/clientTracking.d.ts +22 -0
  10. package/dist/application/clientTracking.d.ts.map +1 -0
  11. package/dist/application/clientTracking.js +122 -0
  12. package/dist/application/clientTracking.js.map +1 -0
  13. package/dist/application/contextFactory.d.ts +97 -0
  14. package/dist/application/contextFactory.d.ts.map +1 -0
  15. package/dist/application/contextFactory.js +169 -0
  16. package/dist/application/contextFactory.js.map +1 -0
  17. package/dist/application/dependencyProcessor.d.ts +11 -0
  18. package/dist/application/dependencyProcessor.d.ts.map +1 -0
  19. package/dist/application/dependencyProcessor.js +69 -0
  20. package/dist/application/dependencyProcessor.js.map +1 -0
  21. package/dist/application/dlqManager.d.ts +12 -0
  22. package/dist/application/dlqManager.d.ts.map +1 -1
  23. package/dist/application/dlqManager.js +36 -0
  24. package/dist/application/dlqManager.js.map +1 -1
  25. package/dist/application/lockManager.d.ts +15 -0
  26. package/dist/application/lockManager.d.ts.map +1 -0
  27. package/dist/application/lockManager.js +118 -0
  28. package/dist/application/lockManager.js.map +1 -0
  29. package/dist/application/lockOperations.d.ts +39 -0
  30. package/dist/application/lockOperations.d.ts.map +1 -0
  31. package/dist/application/lockOperations.js +101 -0
  32. package/dist/application/lockOperations.js.map +1 -0
  33. package/dist/application/operations/ack.d.ts +0 -5
  34. package/dist/application/operations/ack.d.ts.map +1 -1
  35. package/dist/application/operations/ack.js +30 -258
  36. package/dist/application/operations/ack.js.map +1 -1
  37. package/dist/application/operations/ackHelpers.d.ts +78 -0
  38. package/dist/application/operations/ackHelpers.d.ts.map +1 -0
  39. package/dist/application/operations/ackHelpers.js +162 -0
  40. package/dist/application/operations/ackHelpers.js.map +1 -0
  41. package/dist/application/operations/jobManagement.d.ts +2 -0
  42. package/dist/application/operations/jobManagement.d.ts.map +1 -1
  43. package/dist/application/operations/jobManagement.js +8 -0
  44. package/dist/application/operations/jobManagement.js.map +1 -1
  45. package/dist/application/operations/push.d.ts.map +1 -1
  46. package/dist/application/operations/push.js +8 -2
  47. package/dist/application/operations/push.js.map +1 -1
  48. package/dist/application/operations/queryOperations.d.ts +11 -0
  49. package/dist/application/operations/queryOperations.d.ts.map +1 -1
  50. package/dist/application/operations/queryOperations.js +32 -0
  51. package/dist/application/operations/queryOperations.js.map +1 -1
  52. package/dist/application/queueManager.d.ts +13 -183
  53. package/dist/application/queueManager.d.ts.map +1 -1
  54. package/dist/application/queueManager.js +134 -1110
  55. package/dist/application/queueManager.js.map +1 -1
  56. package/dist/application/stallDetection.d.ts +11 -0
  57. package/dist/application/stallDetection.d.ts.map +1 -0
  58. package/dist/application/stallDetection.js +128 -0
  59. package/dist/application/stallDetection.js.map +1 -0
  60. package/dist/application/statsManager.d.ts +56 -0
  61. package/dist/application/statsManager.d.ts.map +1 -0
  62. package/dist/application/statsManager.js +111 -0
  63. package/dist/application/statsManager.js.map +1 -0
  64. package/dist/application/types.d.ts +123 -0
  65. package/dist/application/types.d.ts.map +1 -0
  66. package/dist/application/types.js +16 -0
  67. package/dist/application/types.js.map +1 -0
  68. package/dist/domain/queue/dependencyTracker.d.ts +74 -0
  69. package/dist/domain/queue/dependencyTracker.d.ts.map +1 -0
  70. package/dist/domain/queue/dependencyTracker.js +126 -0
  71. package/dist/domain/queue/dependencyTracker.js.map +1 -0
  72. package/dist/domain/queue/dlqShard.d.ts +59 -0
  73. package/dist/domain/queue/dlqShard.d.ts.map +1 -0
  74. package/dist/domain/queue/dlqShard.js +165 -0
  75. package/dist/domain/queue/dlqShard.js.map +1 -0
  76. package/dist/domain/queue/limiterManager.d.ts +44 -0
  77. package/dist/domain/queue/limiterManager.d.ts.map +1 -0
  78. package/dist/domain/queue/limiterManager.js +99 -0
  79. package/dist/domain/queue/limiterManager.js.map +1 -0
  80. package/dist/domain/queue/shard.d.ts +29 -122
  81. package/dist/domain/queue/shard.d.ts.map +1 -1
  82. package/dist/domain/queue/shard.js +152 -426
  83. package/dist/domain/queue/shard.js.map +1 -1
  84. package/dist/domain/queue/temporalManager.d.ts +81 -0
  85. package/dist/domain/queue/temporalManager.d.ts.map +1 -0
  86. package/dist/domain/queue/temporalManager.js +149 -0
  87. package/dist/domain/queue/temporalManager.js.map +1 -0
  88. package/dist/domain/queue/uniqueKeyManager.d.ts +32 -0
  89. package/dist/domain/queue/uniqueKeyManager.d.ts.map +1 -0
  90. package/dist/domain/queue/uniqueKeyManager.js +87 -0
  91. package/dist/domain/queue/uniqueKeyManager.js.map +1 -0
  92. package/dist/infrastructure/backup/s3Backup.d.ts +3 -40
  93. package/dist/infrastructure/backup/s3Backup.d.ts.map +1 -1
  94. package/dist/infrastructure/backup/s3Backup.js +10 -182
  95. package/dist/infrastructure/backup/s3Backup.js.map +1 -1
  96. package/dist/infrastructure/backup/s3BackupConfig.d.ts +67 -0
  97. package/dist/infrastructure/backup/s3BackupConfig.d.ts.map +1 -0
  98. package/dist/infrastructure/backup/s3BackupConfig.js +48 -0
  99. package/dist/infrastructure/backup/s3BackupConfig.js.map +1 -0
  100. package/dist/infrastructure/backup/s3BackupOperations.d.ts +23 -0
  101. package/dist/infrastructure/backup/s3BackupOperations.d.ts.map +1 -0
  102. package/dist/infrastructure/backup/s3BackupOperations.js +170 -0
  103. package/dist/infrastructure/backup/s3BackupOperations.js.map +1 -0
  104. package/dist/infrastructure/persistence/sqlite.d.ts +4 -13
  105. package/dist/infrastructure/persistence/sqlite.d.ts.map +1 -1
  106. package/dist/infrastructure/persistence/sqlite.js +23 -178
  107. package/dist/infrastructure/persistence/sqlite.js.map +1 -1
  108. package/dist/infrastructure/persistence/sqliteBatch.d.ts +38 -0
  109. package/dist/infrastructure/persistence/sqliteBatch.d.ts.map +1 -0
  110. package/dist/infrastructure/persistence/sqliteBatch.js +124 -0
  111. package/dist/infrastructure/persistence/sqliteBatch.js.map +1 -0
  112. package/dist/infrastructure/persistence/sqliteSerializer.d.ts +17 -0
  113. package/dist/infrastructure/persistence/sqliteSerializer.d.ts.map +1 -0
  114. package/dist/infrastructure/persistence/sqliteSerializer.js +81 -0
  115. package/dist/infrastructure/persistence/sqliteSerializer.js.map +1 -0
  116. package/dist/infrastructure/server/handler.d.ts.map +1 -1
  117. package/dist/infrastructure/server/handler.js +1 -186
  118. package/dist/infrastructure/server/handler.js.map +1 -1
  119. package/dist/infrastructure/server/handlerRoutes.d.ts +23 -0
  120. package/dist/infrastructure/server/handlerRoutes.d.ts.map +1 -0
  121. package/dist/infrastructure/server/handlerRoutes.js +190 -0
  122. package/dist/infrastructure/server/handlerRoutes.js.map +1 -0
  123. package/dist/infrastructure/server/http.d.ts +4 -25
  124. package/dist/infrastructure/server/http.d.ts.map +1 -1
  125. package/dist/infrastructure/server/http.js +43 -285
  126. package/dist/infrastructure/server/http.js.map +1 -1
  127. package/dist/infrastructure/server/httpEndpoints.d.ts +19 -0
  128. package/dist/infrastructure/server/httpEndpoints.d.ts.map +1 -0
  129. package/dist/infrastructure/server/httpEndpoints.js +151 -0
  130. package/dist/infrastructure/server/httpEndpoints.js.map +1 -0
  131. package/dist/infrastructure/server/sseHandler.d.ts +27 -0
  132. package/dist/infrastructure/server/sseHandler.d.ts.map +1 -0
  133. package/dist/infrastructure/server/sseHandler.js +77 -0
  134. package/dist/infrastructure/server/sseHandler.js.map +1 -0
  135. package/dist/infrastructure/server/tcp.d.ts.map +1 -1
  136. package/dist/infrastructure/server/tcp.js +14 -8
  137. package/dist/infrastructure/server/tcp.js.map +1 -1
  138. package/dist/infrastructure/server/wsHandler.d.ts +31 -0
  139. package/dist/infrastructure/server/wsHandler.d.ts.map +1 -0
  140. package/dist/infrastructure/server/wsHandler.js +63 -0
  141. package/dist/infrastructure/server/wsHandler.js.map +1 -0
  142. package/dist/mcp/index.js +3 -465
  143. package/dist/mcp/index.js.map +1 -1
  144. package/dist/mcp/mcpHandlers.d.ts +129 -0
  145. package/dist/mcp/mcpHandlers.d.ts.map +1 -0
  146. package/dist/mcp/mcpHandlers.js +204 -0
  147. package/dist/mcp/mcpHandlers.js.map +1 -0
  148. package/dist/mcp/mcpTools.d.ts +15 -0
  149. package/dist/mcp/mcpTools.d.ts.map +1 -0
  150. package/dist/mcp/mcpTools.js +277 -0
  151. package/dist/mcp/mcpTools.js.map +1 -0
  152. package/package.json +2 -2
  153. package/dist/cli/dashboard.d.ts +0 -32
  154. package/dist/cli/dashboard.d.ts.map +0 -1
  155. package/dist/cli/dashboard.js +0 -183
  156. 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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"}