atomic-queues 1.0.13

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 (110) hide show
  1. package/README.md +686 -0
  2. package/dist/decorators/decorators.d.ts +67 -0
  3. package/dist/decorators/decorators.d.ts.map +1 -0
  4. package/dist/decorators/decorators.js +91 -0
  5. package/dist/decorators/decorators.js.map +1 -0
  6. package/dist/decorators/index.d.ts +2 -0
  7. package/dist/decorators/index.d.ts.map +1 -0
  8. package/dist/decorators/index.js +18 -0
  9. package/dist/decorators/index.js.map +1 -0
  10. package/dist/domain/index.d.ts +5 -0
  11. package/dist/domain/index.d.ts.map +1 -0
  12. package/dist/domain/index.js +21 -0
  13. package/dist/domain/index.js.map +1 -0
  14. package/dist/domain/interfaces.d.ts +614 -0
  15. package/dist/domain/interfaces.d.ts.map +1 -0
  16. package/dist/domain/interfaces.js +19 -0
  17. package/dist/domain/interfaces.js.map +1 -0
  18. package/dist/index.d.ts +40 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +61 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/module/atomic-queues.module.d.ts +97 -0
  23. package/dist/module/atomic-queues.module.d.ts.map +1 -0
  24. package/dist/module/atomic-queues.module.js +197 -0
  25. package/dist/module/atomic-queues.module.js.map +1 -0
  26. package/dist/module/index.d.ts +2 -0
  27. package/dist/module/index.d.ts.map +1 -0
  28. package/dist/module/index.js +18 -0
  29. package/dist/module/index.js.map +1 -0
  30. package/dist/services/constants.d.ts +10 -0
  31. package/dist/services/constants.d.ts.map +1 -0
  32. package/dist/services/constants.js +13 -0
  33. package/dist/services/constants.js.map +1 -0
  34. package/dist/services/cron-manager/cron-manager.service.d.ts +188 -0
  35. package/dist/services/cron-manager/cron-manager.service.d.ts.map +1 -0
  36. package/dist/services/cron-manager/cron-manager.service.js +534 -0
  37. package/dist/services/cron-manager/cron-manager.service.js.map +1 -0
  38. package/dist/services/cron-manager/index.d.ts +2 -0
  39. package/dist/services/cron-manager/index.d.ts.map +1 -0
  40. package/dist/services/cron-manager/index.js +18 -0
  41. package/dist/services/cron-manager/index.js.map +1 -0
  42. package/dist/services/index-manager/index-manager.service.d.ts +146 -0
  43. package/dist/services/index-manager/index-manager.service.d.ts.map +1 -0
  44. package/dist/services/index-manager/index-manager.service.js +337 -0
  45. package/dist/services/index-manager/index-manager.service.js.map +1 -0
  46. package/dist/services/index-manager/index.d.ts +2 -0
  47. package/dist/services/index-manager/index.d.ts.map +1 -0
  48. package/dist/services/index-manager/index.js +18 -0
  49. package/dist/services/index-manager/index.js.map +1 -0
  50. package/dist/services/index.d.ts +10 -0
  51. package/dist/services/index.d.ts.map +1 -0
  52. package/dist/services/index.js +26 -0
  53. package/dist/services/index.js.map +1 -0
  54. package/dist/services/job-processor/index.d.ts +2 -0
  55. package/dist/services/job-processor/index.d.ts.map +1 -0
  56. package/dist/services/job-processor/index.js +18 -0
  57. package/dist/services/job-processor/index.js.map +1 -0
  58. package/dist/services/job-processor/job-processor.service.d.ts +156 -0
  59. package/dist/services/job-processor/job-processor.service.d.ts.map +1 -0
  60. package/dist/services/job-processor/job-processor.service.js +331 -0
  61. package/dist/services/job-processor/job-processor.service.js.map +1 -0
  62. package/dist/services/queue-manager/index.d.ts +2 -0
  63. package/dist/services/queue-manager/index.d.ts.map +1 -0
  64. package/dist/services/queue-manager/index.js +18 -0
  65. package/dist/services/queue-manager/index.js.map +1 -0
  66. package/dist/services/queue-manager/queue-manager.service.d.ts +128 -0
  67. package/dist/services/queue-manager/queue-manager.service.d.ts.map +1 -0
  68. package/dist/services/queue-manager/queue-manager.service.js +308 -0
  69. package/dist/services/queue-manager/queue-manager.service.js.map +1 -0
  70. package/dist/services/resource-lock/index.d.ts +2 -0
  71. package/dist/services/resource-lock/index.d.ts.map +1 -0
  72. package/dist/services/resource-lock/index.js +18 -0
  73. package/dist/services/resource-lock/index.js.map +1 -0
  74. package/dist/services/resource-lock/resource-lock.service.d.ts +124 -0
  75. package/dist/services/resource-lock/resource-lock.service.d.ts.map +1 -0
  76. package/dist/services/resource-lock/resource-lock.service.js +379 -0
  77. package/dist/services/resource-lock/resource-lock.service.js.map +1 -0
  78. package/dist/services/service-queue/index.d.ts +2 -0
  79. package/dist/services/service-queue/index.d.ts.map +1 -0
  80. package/dist/services/service-queue/index.js +18 -0
  81. package/dist/services/service-queue/index.js.map +1 -0
  82. package/dist/services/service-queue/service-queue.service.d.ts +232 -0
  83. package/dist/services/service-queue/service-queue.service.d.ts.map +1 -0
  84. package/dist/services/service-queue/service-queue.service.js +647 -0
  85. package/dist/services/service-queue/service-queue.service.js.map +1 -0
  86. package/dist/services/shutdown-state/index.d.ts +2 -0
  87. package/dist/services/shutdown-state/index.d.ts.map +1 -0
  88. package/dist/services/shutdown-state/index.js +18 -0
  89. package/dist/services/shutdown-state/index.js.map +1 -0
  90. package/dist/services/shutdown-state/shutdown-state.service.d.ts +69 -0
  91. package/dist/services/shutdown-state/shutdown-state.service.d.ts.map +1 -0
  92. package/dist/services/shutdown-state/shutdown-state.service.js +127 -0
  93. package/dist/services/shutdown-state/shutdown-state.service.js.map +1 -0
  94. package/dist/services/worker-manager/index.d.ts +2 -0
  95. package/dist/services/worker-manager/index.d.ts.map +1 -0
  96. package/dist/services/worker-manager/index.js +18 -0
  97. package/dist/services/worker-manager/index.js.map +1 -0
  98. package/dist/services/worker-manager/worker-manager.service.d.ts +163 -0
  99. package/dist/services/worker-manager/worker-manager.service.d.ts.map +1 -0
  100. package/dist/services/worker-manager/worker-manager.service.js +460 -0
  101. package/dist/services/worker-manager/worker-manager.service.js.map +1 -0
  102. package/dist/utils/helpers.d.ts +124 -0
  103. package/dist/utils/helpers.d.ts.map +1 -0
  104. package/dist/utils/helpers.js +229 -0
  105. package/dist/utils/helpers.js.map +1 -0
  106. package/dist/utils/index.d.ts +2 -0
  107. package/dist/utils/index.d.ts.map +1 -0
  108. package/dist/utils/index.js +18 -0
  109. package/dist/utils/index.js.map +1 -0
  110. package/package.json +80 -0
@@ -0,0 +1,534 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ var CronManagerService_1;
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.CronManagerService = void 0;
20
+ const common_1 = require("@nestjs/common");
21
+ const ioredis_1 = __importDefault(require("ioredis"));
22
+ const constants_1 = require("../constants");
23
+ const worker_manager_1 = require("../worker-manager");
24
+ const index_manager_1 = require("../index-manager");
25
+ const service_queue_1 = require("../service-queue");
26
+ /**
27
+ * CronManagerService
28
+ *
29
+ * Manages worker lifecycle through periodic scaling cycles.
30
+ * Implements the patterns from both Whatsapi's CronqProcessor and
31
+ * bl-blackjack-service's WorkerManagerProcessor.
32
+ *
33
+ * Key Features:
34
+ * - Automatic worker spawning when jobs are queued
35
+ * - Worker termination when queues are empty
36
+ * - Concurrency limits based on entity configuration
37
+ * - Queue cleanup after all work is done
38
+ * - Excess worker handling
39
+ *
40
+ * Architecture:
41
+ * - Runs on a configurable interval
42
+ * - Each entity type can register its own scaling logic
43
+ * - Supports per-entity concurrency limits
44
+ * - Integrates with WorkerManager for worker lifecycle
45
+ * - Integrates with IndexManager for state tracking
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * // Register entity scaling configuration
50
+ * cronManager.registerEntityType({
51
+ * entityType: 'user',
52
+ * getDesiredWorkerCount: async (userId) => {
53
+ * const plan = await getUserPlan(userId);
54
+ * return planConcurrencyMap[plan];
55
+ * },
56
+ * getActiveEntityIds: async () => {
57
+ * return indexManager.getEntitiesWithJobs('user');
58
+ * },
59
+ * maxWorkersPerEntity: 5,
60
+ * onSpawnWorker: async (userId) => {
61
+ * await commandBus.execute(new CreateUserWorkerCommand(userId));
62
+ * },
63
+ * });
64
+ *
65
+ * // Start the cron manager
66
+ * cronManager.start(5000); // Run every 5 seconds
67
+ * ```
68
+ */
69
+ let CronManagerService = CronManagerService_1 = class CronManagerService {
70
+ constructor(redis, config, workerManager, indexManager, serviceQueueManager) {
71
+ this.redis = redis;
72
+ this.config = config;
73
+ this.workerManager = workerManager;
74
+ this.indexManager = indexManager;
75
+ this.serviceQueueManager = serviceQueueManager;
76
+ this.logger = new common_1.Logger(CronManagerService_1.name);
77
+ this.entityConfigs = new Map();
78
+ this.cronInterval = null;
79
+ this.running = false;
80
+ this.scalingHandlerRegistered = false;
81
+ this.keyPrefix = config.keyPrefix || 'aq';
82
+ // Use service queue for atomic operations if enabled
83
+ this.useServiceQueue = config.serviceQueue?.enabled !== false;
84
+ // Register the scaling cycle handler with the service queue
85
+ this.registerScalingHandler();
86
+ }
87
+ /**
88
+ * Register the scaling cycle handler with ServiceQueueManager.
89
+ * This ensures scaling cycles are processed atomically by the service worker.
90
+ */
91
+ registerScalingHandler() {
92
+ if (this.scalingHandlerRegistered || !this.serviceQueueManager) {
93
+ return;
94
+ }
95
+ this.serviceQueueManager.registerScalingCycleHandler(async (entityType) => {
96
+ const config = this.entityConfigs.get(entityType);
97
+ if (!config) {
98
+ this.logger.warn(`No config registered for entity type: ${entityType}`);
99
+ return { decisions: [] };
100
+ }
101
+ const decisions = await this.runEntityScalingCycleInternal(entityType, config);
102
+ return { decisions };
103
+ });
104
+ this.scalingHandlerRegistered = true;
105
+ this.logger.debug('Scaling cycle handler registered with ServiceQueueManager');
106
+ }
107
+ /**
108
+ * Register an entity type for automatic scaling.
109
+ */
110
+ registerEntityType(config) {
111
+ this.entityConfigs.set(config.entityType, config);
112
+ this.logger.log(`Registered entity type for scaling: ${config.entityType}`);
113
+ }
114
+ /**
115
+ * Unregister an entity type.
116
+ */
117
+ unregisterEntityType(entityType) {
118
+ this.entityConfigs.delete(entityType);
119
+ this.logger.log(`Unregistered entity type: ${entityType}`);
120
+ }
121
+ /**
122
+ * Run a scaling cycle for all registered entity types.
123
+ *
124
+ * When service queue is enabled, this triggers scaling cycles through the
125
+ * service queue to ensure atomic processing by the single service worker.
126
+ * This prevents race conditions in distributed deployments.
127
+ *
128
+ * IMPORTANT: Only the service worker owner node triggers scaling cycles.
129
+ * Other nodes skip the trigger to prevent duplicate jobs.
130
+ *
131
+ * This is the main logic that:
132
+ * 1. Gets entities with queued jobs
133
+ * 2. Gets entities with running workers
134
+ * 3. Calculates scaling decisions
135
+ * 4. Spawns missing workers
136
+ * 5. Terminates excess workers
137
+ * 6. Cleans up empty queues
138
+ */
139
+ async runScalingCycle() {
140
+ // If service queue is enabled, only the service worker owner should trigger
141
+ if (this.useServiceQueue && this.serviceQueueManager) {
142
+ // Only trigger if we're the service worker owner
143
+ if (this.serviceQueueManager.isServiceWorkerOwner()) {
144
+ await this.triggerScalingCyclesThroughServiceQueue();
145
+ }
146
+ // Return empty - actual decisions are processed by service worker
147
+ return [];
148
+ }
149
+ // Fallback to direct processing (single instance mode)
150
+ return this.runScalingCycleDirectly();
151
+ }
152
+ /**
153
+ * Trigger scaling cycles through the service queue.
154
+ * This ensures only the service worker processes scaling decisions.
155
+ */
156
+ async triggerScalingCyclesThroughServiceQueue() {
157
+ for (const entityType of this.entityConfigs.keys()) {
158
+ try {
159
+ await this.serviceQueueManager.triggerScalingCycle(entityType);
160
+ }
161
+ catch (error) {
162
+ this.logger.error(`Failed to trigger scaling cycle for ${entityType}: ${error.message}`);
163
+ }
164
+ }
165
+ }
166
+ /**
167
+ * Run scaling cycles directly (single instance or fallback mode).
168
+ */
169
+ async runScalingCycleDirectly() {
170
+ const decisions = [];
171
+ for (const [entityType, config] of this.entityConfigs) {
172
+ try {
173
+ const entityDecisions = await this.runEntityScalingCycleInternal(entityType, config);
174
+ decisions.push(...entityDecisions);
175
+ }
176
+ catch (error) {
177
+ this.logger.error(`Error in scaling cycle for ${entityType}: ${error.message}`);
178
+ }
179
+ }
180
+ return decisions;
181
+ }
182
+ /**
183
+ * Get current scaling state for all entity types.
184
+ */
185
+ async getScalingState() {
186
+ const state = new Map();
187
+ for (const [entityType, config] of this.entityConfigs) {
188
+ const entityIds = await config.getActiveEntityIds();
189
+ const decisions = [];
190
+ for (const entityId of entityIds) {
191
+ const currentWorkers = await this.getEntityWorkerCount(entityType, entityId);
192
+ const desiredWorkers = await config.getDesiredWorkerCount(entityId);
193
+ decisions.push({
194
+ entityId,
195
+ entityType,
196
+ currentWorkers,
197
+ desiredWorkers,
198
+ action: this.determineAction(currentWorkers, desiredWorkers),
199
+ count: Math.abs(desiredWorkers - currentWorkers),
200
+ });
201
+ }
202
+ state.set(entityType, decisions);
203
+ }
204
+ return state;
205
+ }
206
+ /**
207
+ * Start the cron manager.
208
+ */
209
+ start(intervalMs) {
210
+ if (this.running) {
211
+ this.logger.warn('CronManager is already running');
212
+ return;
213
+ }
214
+ const interval = intervalMs || this.config.cronInterval || 5000;
215
+ this.logger.log(`Starting CronManager with ${interval}ms interval`);
216
+ this.running = true;
217
+ // Run immediately once
218
+ this.runScalingCycle().catch((error) => {
219
+ this.logger.error(`Initial scaling cycle failed: ${error.message}`);
220
+ });
221
+ // Then run on interval
222
+ this.cronInterval = setInterval(async () => {
223
+ try {
224
+ await this.runScalingCycle();
225
+ }
226
+ catch (error) {
227
+ this.logger.error(`Scaling cycle failed: ${error.message}`);
228
+ }
229
+ }, interval);
230
+ }
231
+ /**
232
+ * Stop the cron manager.
233
+ */
234
+ stop() {
235
+ if (this.cronInterval) {
236
+ clearInterval(this.cronInterval);
237
+ this.cronInterval = null;
238
+ }
239
+ this.running = false;
240
+ this.logger.log('CronManager stopped');
241
+ }
242
+ /**
243
+ * Check if cron manager is running.
244
+ */
245
+ isRunning() {
246
+ return this.running;
247
+ }
248
+ /**
249
+ * Cleanup on module destroy.
250
+ */
251
+ onModuleDestroy() {
252
+ this.stop();
253
+ }
254
+ // =========================================================================
255
+ // PRIVATE METHODS
256
+ // =========================================================================
257
+ /**
258
+ * Run scaling cycle for a specific entity type.
259
+ * This is the internal implementation called either directly or via service queue.
260
+ */
261
+ async runEntityScalingCycleInternal(entityType, config) {
262
+ const decisions = [];
263
+ // Get active entities from the config's getActiveEntityIds (primary source)
264
+ const activeEntityIds = await config.getActiveEntityIds();
265
+ // Get entities with running workers
266
+ const entitiesWithWorkers = await this.getEntitiesWithWorkers(entityType);
267
+ // Spawn missing workers for active entities
268
+ for (const entityId of activeEntityIds) {
269
+ const decision = await this.handleEntitySpawning(entityType, entityId, config, 1);
270
+ if (decision)
271
+ decisions.push(decision);
272
+ }
273
+ // Handle excess workers for active entities
274
+ for (const entityId of activeEntityIds) {
275
+ const decision = await this.handleExcessWorkers(entityType, entityId, config);
276
+ if (decision)
277
+ decisions.push(decision);
278
+ }
279
+ // Close workers for entities with workers but no longer active
280
+ const activeEntitySet = new Set(activeEntityIds);
281
+ const entitiesWithWorkersNoLongerActive = Array.from(entitiesWithWorkers).filter((entityId) => !activeEntitySet.has(entityId));
282
+ for (const entityId of entitiesWithWorkersNoLongerActive) {
283
+ const decision = await this.handleWorkerClosure(entityType, entityId, config);
284
+ if (decision)
285
+ decisions.push(decision);
286
+ }
287
+ return decisions;
288
+ }
289
+ /**
290
+ * Handle worker spawning for an entity.
291
+ */
292
+ async handleEntitySpawning(entityType, entityId, config, queuedJobCount) {
293
+ const currentWorkers = await this.getEntityWorkerCount(entityType, entityId);
294
+ const desiredWorkers = await config.getDesiredWorkerCount(entityId);
295
+ const maxWorkers = config.maxWorkersPerEntity || desiredWorkers;
296
+ // Calculate how many workers we should have
297
+ const targetWorkers = Math.min(desiredWorkers, maxWorkers, queuedJobCount);
298
+ if (currentWorkers >= targetWorkers) {
299
+ return null;
300
+ }
301
+ const toSpawn = targetWorkers - currentWorkers;
302
+ this.logger.debug(`Spawning ${toSpawn} workers for ${entityType}/${entityId}`);
303
+ // Track worker creation requests to avoid over-spawning
304
+ const pendingCreations = await this.getPendingWorkerCreations(entityType, entityId);
305
+ const actualToSpawn = Math.max(0, toSpawn - pendingCreations);
306
+ for (let i = 0; i < actualToSpawn; i++) {
307
+ await this.incrementWorkerCreationRequest(entityType, entityId);
308
+ if (config.onSpawnWorker) {
309
+ try {
310
+ await config.onSpawnWorker(entityId);
311
+ }
312
+ catch (error) {
313
+ this.logger.error(`Failed to spawn worker for ${entityType}/${entityId}: ${error.message}`);
314
+ await this.decrementWorkerCreationRequest(entityType, entityId);
315
+ }
316
+ }
317
+ }
318
+ return {
319
+ entityId,
320
+ entityType,
321
+ currentWorkers,
322
+ desiredWorkers: targetWorkers,
323
+ action: 'spawn',
324
+ count: actualToSpawn,
325
+ };
326
+ }
327
+ /**
328
+ * Handle excess workers for an entity.
329
+ */
330
+ async handleExcessWorkers(entityType, entityId, config) {
331
+ const currentWorkers = await this.getEntityWorkerCount(entityType, entityId);
332
+ const desiredWorkers = await config.getDesiredWorkerCount(entityId);
333
+ const maxWorkers = config.maxWorkersPerEntity || desiredWorkers;
334
+ if (currentWorkers <= maxWorkers) {
335
+ return null;
336
+ }
337
+ const excess = currentWorkers - maxWorkers;
338
+ this.logger.debug(`Terminating ${excess} excess workers for ${entityType}/${entityId}`);
339
+ // Queue worker termination
340
+ const pendingDeaths = await this.indexManager.getQueuedWorkerDeaths(entityType, entityId);
341
+ if (pendingDeaths.length === 0 && excess > 0) {
342
+ await this.queueWorkerTermination(entityType, entityId, config);
343
+ }
344
+ return {
345
+ entityId,
346
+ entityType,
347
+ currentWorkers,
348
+ desiredWorkers: maxWorkers,
349
+ action: 'terminate',
350
+ count: excess,
351
+ };
352
+ }
353
+ /**
354
+ * Handle worker closure for entities with no jobs.
355
+ * Only terminates workers if the entity's queue is truly empty (no waiting or active jobs).
356
+ */
357
+ async handleWorkerClosure(entityType, entityId, config) {
358
+ const workers = await this.workerManager.getEntityWorkers(entityType, entityId);
359
+ if (workers.length === 0) {
360
+ return null;
361
+ }
362
+ // Check if there are pending or active jobs in the queue
363
+ // Don't terminate workers that might still be processing jobs
364
+ const queueName = `${entityId}-queue`;
365
+ const hasActiveJobs = await this.checkQueueHasJobs(queueName);
366
+ if (hasActiveJobs) {
367
+ this.logger.debug(`Skipping worker closure for ${entityType}/${entityId} - queue has active jobs`);
368
+ return null;
369
+ }
370
+ this.logger.debug(`Closing ${workers.length} workers for empty ${entityType}/${entityId}`);
371
+ // Signal all workers to close
372
+ for (const workerId of workers) {
373
+ if (config.onTerminateWorker) {
374
+ await config.onTerminateWorker(entityId, workerId);
375
+ }
376
+ else {
377
+ await this.workerManager.signalWorkerClose(workerId);
378
+ }
379
+ }
380
+ return {
381
+ entityId,
382
+ entityType,
383
+ currentWorkers: workers.length,
384
+ desiredWorkers: 0,
385
+ action: 'terminate',
386
+ count: workers.length,
387
+ };
388
+ }
389
+ /**
390
+ * Check if a queue has any waiting or active jobs.
391
+ */
392
+ async checkQueueHasJobs(queueName) {
393
+ try {
394
+ // Check waiting list
395
+ const waitingKey = `bull:${queueName}:waiting`;
396
+ const waitingCount = await this.redis.llen(waitingKey);
397
+ if (waitingCount > 0)
398
+ return true;
399
+ // Check active list
400
+ const activeKey = `bull:${queueName}:active`;
401
+ const activeCount = await this.redis.llen(activeKey);
402
+ if (activeCount > 0)
403
+ return true;
404
+ // Check delayed set
405
+ const delayedKey = `bull:${queueName}:delayed`;
406
+ const delayedCount = await this.redis.zcard(delayedKey);
407
+ if (delayedCount > 0)
408
+ return true;
409
+ return false;
410
+ }
411
+ catch (error) {
412
+ this.logger.warn(`Error checking queue ${queueName} for jobs: ${error.message}`);
413
+ // If we can't check, don't terminate (safer)
414
+ return true;
415
+ }
416
+ }
417
+ /**
418
+ * Handle queue cleanup for entities with no jobs and no workers.
419
+ */
420
+ async handleQueueCleanup(entityType, entityId) {
421
+ // Check if there's already a queue death queued
422
+ const pendingQueueDeaths = await this.indexManager.getEntitiesWithQueuedQueueDeaths(entityType);
423
+ if (pendingQueueDeaths.includes(entityId)) {
424
+ return;
425
+ }
426
+ this.logger.debug(`Cleaning up queue for ${entityType}/${entityId}`);
427
+ // Index the queue death
428
+ await this.indexManager.indexQueueDeath(entityType, entityId);
429
+ // The actual queue cleanup should be handled by a separate processor
430
+ // or by the entity's cleanup callback
431
+ }
432
+ /**
433
+ * Queue worker termination via the entity's queue.
434
+ */
435
+ async queueWorkerTermination(entityType, entityId, config) {
436
+ // This is a placeholder - actual implementation would queue a SIGTERM
437
+ // job to the entity's queue, which the worker would pick up and
438
+ // gracefully terminate itself (like in Whatsapi)
439
+ this.logger.debug(`Queued worker termination for ${entityType}/${entityId}`);
440
+ }
441
+ /**
442
+ * Get the number of workers for an entity.
443
+ * Uses the worker heartbeat TTL keys as the single source of truth.
444
+ * This is a direct Redis query - no service queue needed since we're just reading keys.
445
+ */
446
+ async getEntityWorkerCount(entityType, entityId) {
447
+ // Direct query to worker heartbeat TTL keys - the single source of truth
448
+ const workers = await this.workerManager.getEntityWorkers(entityType, entityId);
449
+ return workers.length;
450
+ }
451
+ /**
452
+ * Get all entities with workers.
453
+ * Uses the worker heartbeat TTL keys as the single source of truth.
454
+ * Worker names follow pattern: {entityId}-worker
455
+ */
456
+ async getEntitiesWithWorkers(entityType) {
457
+ // Worker heartbeat keys follow pattern: {prefix}:worker:{nodeId}:{entityId}-worker
458
+ const pattern = `${this.keyPrefix}:worker:*:*-worker`;
459
+ const keys = await this.scanKeys(pattern);
460
+ const entities = new Set();
461
+ for (const key of keys) {
462
+ const parts = key.split(':');
463
+ if (parts.length >= 4) {
464
+ // workerName is last part, extract entityId by removing '-worker' suffix
465
+ const workerName = parts[parts.length - 1];
466
+ if (workerName.endsWith('-worker')) {
467
+ const entityId = workerName.slice(0, -7); // Remove '-worker' suffix
468
+ entities.add(entityId);
469
+ }
470
+ }
471
+ }
472
+ return entities;
473
+ }
474
+ /**
475
+ * Get pending worker creation requests count.
476
+ */
477
+ async getPendingWorkerCreations(entityType, entityId) {
478
+ const key = `${this.keyPrefix}:worker-creation:${entityType}:${entityId}`;
479
+ const count = await this.redis.get(key);
480
+ return count ? parseInt(count, 10) : 0;
481
+ }
482
+ /**
483
+ * Increment worker creation request counter.
484
+ */
485
+ async incrementWorkerCreationRequest(entityType, entityId) {
486
+ const key = `${this.keyPrefix}:worker-creation:${entityType}:${entityId}`;
487
+ await this.redis.incr(key);
488
+ await this.redis.expire(key, 60); // TTL for cleanup
489
+ }
490
+ /**
491
+ * Decrement worker creation request counter.
492
+ */
493
+ async decrementWorkerCreationRequest(entityType, entityId) {
494
+ const key = `${this.keyPrefix}:worker-creation:${entityType}:${entityId}`;
495
+ const current = await this.redis.get(key);
496
+ if (current && parseInt(current, 10) > 0) {
497
+ await this.redis.decr(key);
498
+ }
499
+ }
500
+ /**
501
+ * Determine the scaling action based on current vs desired.
502
+ */
503
+ determineAction(current, desired) {
504
+ if (current < desired)
505
+ return 'spawn';
506
+ if (current > desired)
507
+ return 'terminate';
508
+ return 'none';
509
+ }
510
+ /**
511
+ * Scan Redis keys matching a pattern.
512
+ */
513
+ async scanKeys(pattern) {
514
+ let cursor = '0';
515
+ const keys = [];
516
+ do {
517
+ const [nextCursor, scanKeys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
518
+ cursor = nextCursor;
519
+ keys.push(...scanKeys);
520
+ } while (cursor !== '0');
521
+ return keys;
522
+ }
523
+ };
524
+ exports.CronManagerService = CronManagerService;
525
+ exports.CronManagerService = CronManagerService = CronManagerService_1 = __decorate([
526
+ (0, common_1.Injectable)(),
527
+ __param(0, (0, common_1.Inject)(constants_1.ATOMIC_QUEUES_REDIS)),
528
+ __param(1, (0, common_1.Inject)(constants_1.ATOMIC_QUEUES_CONFIG)),
529
+ __param(4, (0, common_1.Optional)()),
530
+ __metadata("design:paramtypes", [ioredis_1.default, Object, worker_manager_1.WorkerManagerService,
531
+ index_manager_1.IndexManagerService,
532
+ service_queue_1.ServiceQueueManager])
533
+ ], CronManagerService);
534
+ //# sourceMappingURL=cron-manager.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-manager.service.js","sourceRoot":"","sources":["../../../src/services/cron-manager/cron-manager.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './cron-manager.service';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/cron-manager/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./cron-manager.service"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/cron-manager/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,yDAAuC"}