atomic-queues 1.4.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +300 -283
- package/dist/decorators/constants.d.ts +17 -0
- package/dist/decorators/constants.d.ts.map +1 -0
- package/dist/decorators/constants.js +23 -0
- package/dist/decorators/constants.js.map +1 -0
- package/dist/decorators/entity.decorators.d.ts +88 -0
- package/dist/decorators/entity.decorators.d.ts.map +1 -0
- package/dist/decorators/entity.decorators.js +150 -0
- package/dist/decorators/entity.decorators.js.map +1 -0
- package/dist/decorators/index.d.ts +9 -1
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +9 -1
- package/dist/decorators/index.js.map +1 -1
- package/dist/decorators/interfaces.d.ts +130 -0
- package/dist/decorators/interfaces.d.ts.map +1 -0
- package/dist/decorators/interfaces.js +3 -0
- package/dist/decorators/interfaces.js.map +1 -0
- package/dist/decorators/job.decorators.d.ts +60 -0
- package/dist/decorators/job.decorators.d.ts.map +1 -0
- package/dist/decorators/job.decorators.js +97 -0
- package/dist/decorators/job.decorators.js.map +1 -0
- package/dist/decorators/legacy.decorators.d.ts +36 -0
- package/dist/decorators/legacy.decorators.d.ts.map +1 -0
- package/dist/decorators/legacy.decorators.js +61 -0
- package/dist/decorators/legacy.decorators.js.map +1 -0
- package/dist/decorators/metadata-readers.d.ts +31 -0
- package/dist/decorators/metadata-readers.d.ts.map +1 -0
- package/dist/decorators/metadata-readers.js +53 -0
- package/dist/decorators/metadata-readers.js.map +1 -0
- package/dist/decorators/registry.d.ts +2 -0
- package/dist/decorators/registry.d.ts.map +1 -0
- package/dist/decorators/registry.js +6 -0
- package/dist/decorators/registry.js.map +1 -0
- package/dist/decorators/scaler.decorators.d.ts +65 -0
- package/dist/decorators/scaler.decorators.d.ts.map +1 -0
- package/dist/decorators/scaler.decorators.js +103 -0
- package/dist/decorators/scaler.decorators.js.map +1 -0
- package/dist/decorators/type-guards.d.ts +18 -0
- package/dist/decorators/type-guards.d.ts.map +1 -0
- package/dist/decorators/type-guards.js +32 -0
- package/dist/decorators/type-guards.js.map +1 -0
- package/dist/decorators/utils.d.ts +20 -0
- package/dist/decorators/utils.d.ts.map +1 -0
- package/dist/decorators/utils.js +98 -0
- package/dist/decorators/utils.js.map +1 -0
- package/dist/decorators/worker.decorators.d.ts +58 -0
- package/dist/decorators/worker.decorators.d.ts.map +1 -0
- package/dist/decorators/worker.decorators.js +92 -0
- package/dist/decorators/worker.decorators.js.map +1 -0
- package/dist/domain/interfaces/config.interfaces.d.ts +188 -0
- package/dist/domain/interfaces/config.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/config.interfaces.js +3 -0
- package/dist/domain/interfaces/config.interfaces.js.map +1 -0
- package/dist/domain/interfaces/cqrs.interfaces.d.ts +7 -0
- package/dist/domain/interfaces/cqrs.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/cqrs.interfaces.js +3 -0
- package/dist/domain/interfaces/cqrs.interfaces.js.map +1 -0
- package/dist/domain/interfaces/event.interfaces.d.ts +71 -0
- package/dist/domain/interfaces/event.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/event.interfaces.js +3 -0
- package/dist/domain/interfaces/event.interfaces.js.map +1 -0
- package/dist/domain/interfaces/index-tracking.interfaces.d.ts +69 -0
- package/dist/domain/interfaces/index-tracking.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/index-tracking.interfaces.js +3 -0
- package/dist/domain/interfaces/index-tracking.interfaces.js.map +1 -0
- package/dist/domain/interfaces/index.d.ts +12 -0
- package/dist/domain/interfaces/index.d.ts.map +1 -0
- package/dist/domain/interfaces/index.js +28 -0
- package/dist/domain/interfaces/index.js.map +1 -0
- package/dist/domain/interfaces/job.interfaces.d.ts +76 -0
- package/dist/domain/interfaces/job.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/job.interfaces.js +3 -0
- package/dist/domain/interfaces/job.interfaces.js.map +1 -0
- package/dist/domain/interfaces/lock.interfaces.d.ts +54 -0
- package/dist/domain/interfaces/lock.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/lock.interfaces.js +3 -0
- package/dist/domain/interfaces/lock.interfaces.js.map +1 -0
- package/dist/domain/interfaces/process.interfaces.d.ts +44 -0
- package/dist/domain/interfaces/process.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/process.interfaces.js +3 -0
- package/dist/domain/interfaces/process.interfaces.js.map +1 -0
- package/dist/domain/interfaces/queue.interfaces.d.ts +46 -0
- package/dist/domain/interfaces/queue.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/queue.interfaces.js +3 -0
- package/dist/domain/interfaces/queue.interfaces.js.map +1 -0
- package/dist/domain/interfaces/scaling.interfaces.d.ts +62 -0
- package/dist/domain/interfaces/scaling.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/scaling.interfaces.js +3 -0
- package/dist/domain/interfaces/scaling.interfaces.js.map +1 -0
- package/dist/domain/interfaces/utility.types.d.ts +15 -0
- package/dist/domain/interfaces/utility.types.d.ts.map +1 -0
- package/dist/domain/interfaces/utility.types.js +3 -0
- package/dist/domain/interfaces/utility.types.js.map +1 -0
- package/dist/domain/interfaces/worker.interfaces.d.ts +120 -0
- package/dist/domain/interfaces/worker.interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces/worker.interfaces.js +3 -0
- package/dist/domain/interfaces/worker.interfaces.js.map +1 -0
- package/dist/module/atomic-queues.module.d.ts.map +1 -1
- package/dist/module/atomic-queues.module.js +5 -0
- package/dist/module/atomic-queues.module.js.map +1 -1
- package/dist/services/cron-manager/cron-manager.service.d.ts +5 -4
- package/dist/services/cron-manager/cron-manager.service.d.ts.map +1 -1
- package/dist/services/cron-manager/cron-manager.service.js +26 -57
- package/dist/services/cron-manager/cron-manager.service.js.map +1 -1
- package/dist/services/index-manager/index-manager.service.d.ts +0 -4
- package/dist/services/index-manager/index-manager.service.d.ts.map +1 -1
- package/dist/services/index-manager/index-manager.service.js +4 -16
- package/dist/services/index-manager/index-manager.service.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/processor-discovery/decorator-discovery.service.d.ts +40 -0
- package/dist/services/processor-discovery/decorator-discovery.service.d.ts.map +1 -0
- package/dist/services/processor-discovery/decorator-discovery.service.js +191 -0
- package/dist/services/processor-discovery/decorator-discovery.service.js.map +1 -0
- package/dist/services/processor-discovery/index.d.ts +4 -0
- package/dist/services/processor-discovery/index.d.ts.map +1 -1
- package/dist/services/processor-discovery/index.js +4 -0
- package/dist/services/processor-discovery/index.js.map +1 -1
- package/dist/services/processor-discovery/processor-discovery.service.d.ts +30 -138
- package/dist/services/processor-discovery/processor-discovery.service.d.ts.map +1 -1
- package/dist/services/processor-discovery/processor-discovery.service.js +125 -502
- package/dist/services/processor-discovery/processor-discovery.service.js.map +1 -1
- package/dist/services/processor-discovery/processor-registry.d.ts +58 -0
- package/dist/services/processor-discovery/processor-registry.d.ts.map +1 -0
- package/dist/services/processor-discovery/processor-registry.js +74 -0
- package/dist/services/processor-discovery/processor-registry.js.map +1 -0
- package/dist/services/processor-discovery/scaling-registration.service.d.ts +60 -0
- package/dist/services/processor-discovery/scaling-registration.service.d.ts.map +1 -0
- package/dist/services/processor-discovery/scaling-registration.service.js +261 -0
- package/dist/services/processor-discovery/scaling-registration.service.js.map +1 -0
- package/dist/services/processor-discovery/worker-factory.service.d.ts +54 -0
- package/dist/services/processor-discovery/worker-factory.service.d.ts.map +1 -0
- package/dist/services/processor-discovery/worker-factory.service.js +185 -0
- package/dist/services/processor-discovery/worker-factory.service.js.map +1 -0
- package/dist/services/queue-bus/entity-target.d.ts +58 -0
- package/dist/services/queue-bus/entity-target.d.ts.map +1 -0
- package/dist/services/queue-bus/entity-target.js +109 -0
- package/dist/services/queue-bus/entity-target.js.map +1 -0
- package/dist/services/queue-bus/index.d.ts +4 -0
- package/dist/services/queue-bus/index.d.ts.map +1 -1
- package/dist/services/queue-bus/index.js +4 -0
- package/dist/services/queue-bus/index.js.map +1 -1
- package/dist/services/queue-bus/queue-bus.service.d.ts +9 -145
- package/dist/services/queue-bus/queue-bus.service.d.ts.map +1 -1
- package/dist/services/queue-bus/queue-bus.service.js +23 -311
- package/dist/services/queue-bus/queue-bus.service.js.map +1 -1
- package/dist/services/queue-bus/queue-bus.types.d.ts +40 -0
- package/dist/services/queue-bus/queue-bus.types.d.ts.map +1 -0
- package/dist/services/queue-bus/queue-bus.types.js +3 -0
- package/dist/services/queue-bus/queue-bus.types.js.map +1 -0
- package/dist/services/queue-bus/queue-bus.utils.d.ts +34 -0
- package/dist/services/queue-bus/queue-bus.utils.d.ts.map +1 -0
- package/dist/services/queue-bus/queue-bus.utils.js +82 -0
- package/dist/services/queue-bus/queue-bus.utils.js.map +1 -0
- package/dist/services/queue-bus/queue-target.d.ts +61 -0
- package/dist/services/queue-bus/queue-target.d.ts.map +1 -0
- package/dist/services/queue-bus/queue-target.js +123 -0
- package/dist/services/queue-bus/queue-target.js.map +1 -0
- package/dist/services/queue-events-manager/queue-events-manager.service.d.ts +23 -6
- package/dist/services/queue-events-manager/queue-events-manager.service.d.ts.map +1 -1
- package/dist/services/queue-events-manager/queue-events-manager.service.js +69 -37
- package/dist/services/queue-events-manager/queue-events-manager.service.js.map +1 -1
- package/dist/services/resource-lock/resource-lock.service.d.ts +0 -4
- package/dist/services/resource-lock/resource-lock.service.d.ts.map +1 -1
- package/dist/services/resource-lock/resource-lock.service.js +4 -16
- package/dist/services/resource-lock/resource-lock.service.js.map +1 -1
- package/dist/services/service-queue/index.d.ts +1 -0
- package/dist/services/service-queue/index.d.ts.map +1 -1
- package/dist/services/service-queue/index.js +1 -0
- package/dist/services/service-queue/index.js.map +1 -1
- package/dist/services/service-queue/service-queue.service.d.ts +2 -35
- package/dist/services/service-queue/service-queue.service.d.ts.map +1 -1
- package/dist/services/service-queue/service-queue.service.js +17 -49
- package/dist/services/service-queue/service-queue.service.js.map +1 -1
- package/dist/services/service-queue/service-queue.types.d.ts +32 -0
- package/dist/services/service-queue/service-queue.types.d.ts.map +1 -0
- package/dist/services/service-queue/service-queue.types.js +27 -0
- package/dist/services/service-queue/service-queue.types.js.map +1 -0
- package/dist/services/spawn-queue/index.d.ts +2 -0
- package/dist/services/spawn-queue/index.d.ts.map +1 -0
- package/dist/services/spawn-queue/index.js +18 -0
- package/dist/services/spawn-queue/index.js.map +1 -0
- package/dist/services/spawn-queue/spawn-queue.service.d.ts +119 -0
- package/dist/services/spawn-queue/spawn-queue.service.d.ts.map +1 -0
- package/dist/services/spawn-queue/spawn-queue.service.js +273 -0
- package/dist/services/spawn-queue/spawn-queue.service.js.map +1 -0
- package/dist/services/worker-manager/worker-manager.service.d.ts +18 -3
- package/dist/services/worker-manager/worker-manager.service.d.ts.map +1 -1
- package/dist/services/worker-manager/worker-manager.service.js +46 -21
- package/dist/services/worker-manager/worker-manager.service.js.map +1 -1
- package/dist/utils/async.utils.d.ts +51 -0
- package/dist/utils/async.utils.d.ts.map +1 -0
- package/dist/utils/async.utils.js +87 -0
- package/dist/utils/async.utils.js.map +1 -0
- package/dist/utils/helpers.d.ts +4 -123
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/helpers.js +18 -226
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/job.utils.d.ts +50 -0
- package/dist/utils/job.utils.d.ts.map +1 -0
- package/dist/utils/job.utils.js +89 -0
- package/dist/utils/job.utils.js.map +1 -0
- package/dist/utils/naming.utils.d.ts +21 -0
- package/dist/utils/naming.utils.d.ts.map +1 -0
- package/dist/utils/naming.utils.js +38 -0
- package/dist/utils/naming.utils.js.map +1 -0
- package/dist/utils/rate-limit.utils.d.ts +9 -0
- package/dist/utils/rate-limit.utils.d.ts.map +1 -0
- package/dist/utils/rate-limit.utils.js +30 -0
- package/dist/utils/rate-limit.utils.js.map +1 -0
- package/dist/utils/redis.utils.d.ts +3 -0
- package/dist/utils/redis.utils.d.ts.map +1 -0
- package/dist/utils/redis.utils.js +14 -0
- package/dist/utils/redis.utils.js.map +1 -0
- package/package.json +17 -17
- package/dist/decorators/decorators.d.ts +0 -489
- package/dist/decorators/decorators.d.ts.map +0 -1
- package/dist/decorators/decorators.js +0 -680
- package/dist/decorators/decorators.js.map +0 -1
- package/dist/domain/interfaces.d.ts +0 -748
- package/dist/domain/interfaces.d.ts.map +0 -1
- package/dist/domain/interfaces.js +0 -19
- package/dist/domain/interfaces.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lock state for a resource
|
|
3
|
+
*/
|
|
4
|
+
export interface IResourceLock {
|
|
5
|
+
resourceId: string;
|
|
6
|
+
resourceType: string;
|
|
7
|
+
ownerId: string;
|
|
8
|
+
ownerType: string;
|
|
9
|
+
acquiredAt: Date;
|
|
10
|
+
expiresAt: Date;
|
|
11
|
+
metadata?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Lock acquisition result
|
|
15
|
+
*/
|
|
16
|
+
export interface ILockResult {
|
|
17
|
+
acquired: boolean;
|
|
18
|
+
lock?: IResourceLock;
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resource lock service interface for distributed locking
|
|
23
|
+
*/
|
|
24
|
+
export interface IResourceLockService {
|
|
25
|
+
/**
|
|
26
|
+
* Acquire a lock on a resource
|
|
27
|
+
*/
|
|
28
|
+
acquireLock(resourceType: string, resourceId: string, ownerId: string, ownerType: string, ttlSeconds?: number, metadata?: Record<string, unknown>): Promise<ILockResult>;
|
|
29
|
+
/**
|
|
30
|
+
* Release a lock on a resource
|
|
31
|
+
*/
|
|
32
|
+
releaseLock(resourceType: string, resourceId: string): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Check if a resource is locked
|
|
35
|
+
*/
|
|
36
|
+
isLocked(resourceType: string, resourceId: string): Promise<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Get lock info for a resource
|
|
39
|
+
*/
|
|
40
|
+
getLockInfo(resourceType: string, resourceId: string): Promise<IResourceLock | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Get all locked resources of a type for an owner
|
|
43
|
+
*/
|
|
44
|
+
getOwnerLocks(ownerType: string, ownerId: string): Promise<IResourceLock[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get available (unlocked) resource from a pool
|
|
47
|
+
*/
|
|
48
|
+
getAvailableResource(resourceType: string, candidateIds: string[], ownerId: string, ownerType: string, ttlSeconds?: number): Promise<ILockResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Extend lock TTL
|
|
51
|
+
*/
|
|
52
|
+
extendLock(resourceType: string, resourceId: string, ttlSeconds: number): Promise<boolean>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=lock.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.interfaces.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/lock.interfaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,WAAW,CACT,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExE;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAErE;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IAErF;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAE5E;;OAEG;IACH,oBAAoB,CAClB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EAAE,EACtB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB;;OAEG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.interfaces.js","sourceRoot":"","sources":["../../../src/domain/interfaces/lock.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Atomic process status
|
|
3
|
+
*/
|
|
4
|
+
export type AtomicProcessStatus = 'pending' | 'processing' | 'completed' | 'failed';
|
|
5
|
+
/**
|
|
6
|
+
* Atomic process state
|
|
7
|
+
*/
|
|
8
|
+
export interface IAtomicProcessState {
|
|
9
|
+
uuid: string;
|
|
10
|
+
status: AtomicProcessStatus;
|
|
11
|
+
entityId: string;
|
|
12
|
+
entityType: string;
|
|
13
|
+
commandName?: string;
|
|
14
|
+
createdAt: Date;
|
|
15
|
+
updatedAt: Date;
|
|
16
|
+
result?: unknown;
|
|
17
|
+
error?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Atomic process status tracker interface
|
|
21
|
+
*/
|
|
22
|
+
export interface IAtomicProcessTracker {
|
|
23
|
+
/**
|
|
24
|
+
* Set process status
|
|
25
|
+
*/
|
|
26
|
+
setStatus(uuid: string, status: AtomicProcessStatus): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Get process status
|
|
29
|
+
*/
|
|
30
|
+
getStatus(uuid: string): Promise<IAtomicProcessState | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Set process result
|
|
33
|
+
*/
|
|
34
|
+
setResult(uuid: string, result: unknown): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Set process error
|
|
37
|
+
*/
|
|
38
|
+
setError(uuid: string, error: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Clean up old process states
|
|
41
|
+
*/
|
|
42
|
+
cleanup(maxAgeMs?: number): Promise<number>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=process.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.interfaces.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/process.interfaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,mBAAmB,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpE;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;IAE7D;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.interfaces.js","sourceRoot":"","sources":["../../../src/domain/interfaces/process.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Queue, Job } from 'bullmq';
|
|
2
|
+
import { IJobOptions } from './config.interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Represents a managed queue instance
|
|
5
|
+
*/
|
|
6
|
+
export interface IManagedQueue {
|
|
7
|
+
name: string;
|
|
8
|
+
queue: Queue;
|
|
9
|
+
createdAt: Date;
|
|
10
|
+
entityId: string;
|
|
11
|
+
entityType: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Queue manager service interface for dynamic queue creation/destruction
|
|
15
|
+
*/
|
|
16
|
+
export interface IQueueManager {
|
|
17
|
+
/**
|
|
18
|
+
* Get or create a queue for the given name
|
|
19
|
+
*/
|
|
20
|
+
getOrCreateQueue(queueName: string): Queue;
|
|
21
|
+
/**
|
|
22
|
+
* Get or create an entity-specific queue
|
|
23
|
+
*/
|
|
24
|
+
getOrCreateEntityQueue(entityType: string, entityId: string): Queue;
|
|
25
|
+
/**
|
|
26
|
+
* Close and remove a specific queue
|
|
27
|
+
*/
|
|
28
|
+
closeQueue(queueName: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Close all managed queues
|
|
31
|
+
*/
|
|
32
|
+
closeAllQueues(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Get all queue names
|
|
35
|
+
*/
|
|
36
|
+
getQueueNames(): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Delete a specific job from a queue
|
|
39
|
+
*/
|
|
40
|
+
deleteJob(queueName: string, jobId: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Add a job to a queue
|
|
43
|
+
*/
|
|
44
|
+
addJob<T>(queueName: string, jobName: string, data: T, options?: IJobOptions): Promise<Job<T>>;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=queue.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.interfaces.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/queue.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;IAE3C;;OAEG;IACH,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;IAEpE;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C;;OAEG;IACH,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3D;;OAEG;IACH,MAAM,CAAC,CAAC,EACN,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.interfaces.js","sourceRoot":"","sources":["../../../src/domain/interfaces/queue.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker scaling decision
|
|
3
|
+
*/
|
|
4
|
+
export interface IScalingDecision {
|
|
5
|
+
entityId: string;
|
|
6
|
+
entityType: string;
|
|
7
|
+
currentWorkers: number;
|
|
8
|
+
desiredWorkers: number;
|
|
9
|
+
action: 'spawn' | 'terminate' | 'none';
|
|
10
|
+
count: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Entity scaling configuration
|
|
14
|
+
*/
|
|
15
|
+
export interface IEntityScalingConfig {
|
|
16
|
+
entityType: string;
|
|
17
|
+
/** Function to get desired worker count for an entity */
|
|
18
|
+
getDesiredWorkerCount: (entityId: string) => Promise<number>;
|
|
19
|
+
/** Function to get all active entity IDs */
|
|
20
|
+
getActiveEntityIds: () => Promise<string[]>;
|
|
21
|
+
/** Maximum workers per entity */
|
|
22
|
+
maxWorkersPerEntity?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Idle timeout in seconds before a worker is considered idle and can be terminated.
|
|
25
|
+
* Workers self-report idle time via heartbeat. Default: 15 seconds.
|
|
26
|
+
*/
|
|
27
|
+
idleTimeoutSeconds?: number;
|
|
28
|
+
/** Function called when spawning a worker */
|
|
29
|
+
onSpawnWorker?: (entityId: string) => Promise<void>;
|
|
30
|
+
/** Function called when terminating a worker */
|
|
31
|
+
onTerminateWorker?: (entityId: string, workerId: string) => Promise<void>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Cron manager interface for worker lifecycle management
|
|
35
|
+
*/
|
|
36
|
+
export interface ICronManager {
|
|
37
|
+
/**
|
|
38
|
+
* Register an entity type for automatic scaling
|
|
39
|
+
*/
|
|
40
|
+
registerEntityType(config: IEntityScalingConfig): void;
|
|
41
|
+
/**
|
|
42
|
+
* Run scaling cycle for all registered entity types
|
|
43
|
+
*/
|
|
44
|
+
runScalingCycle(): Promise<IScalingDecision[]>;
|
|
45
|
+
/**
|
|
46
|
+
* Get current scaling state
|
|
47
|
+
*/
|
|
48
|
+
getScalingState(): Promise<Map<string, IScalingDecision[]>>;
|
|
49
|
+
/**
|
|
50
|
+
* Start the cron manager
|
|
51
|
+
*/
|
|
52
|
+
start(intervalMs?: number): void;
|
|
53
|
+
/**
|
|
54
|
+
* Stop the cron manager
|
|
55
|
+
*/
|
|
56
|
+
stop(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Check if cron manager is running
|
|
59
|
+
*/
|
|
60
|
+
isRunning(): boolean;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=scaling.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaling.interfaces.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/scaling.interfaces.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,CAAC;IACvC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,qBAAqB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,4CAA4C;IAC5C,kBAAkB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,iCAAiC;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,6CAA6C;IAC7C,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAEvD;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC;IAE5D;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;OAEG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;OAEG;IACH,SAAS,IAAI,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaling.interfaces.js","sourceRoot":"","sources":["../../../src/domain/interfaces/scaling.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deep partial type utility
|
|
3
|
+
*/
|
|
4
|
+
export type DeepPartial<T> = {
|
|
5
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Constructor type
|
|
9
|
+
*/
|
|
10
|
+
export type Constructor<T = unknown> = new (...args: unknown[]) => T;
|
|
11
|
+
/**
|
|
12
|
+
* Async factory function type
|
|
13
|
+
*/
|
|
14
|
+
export type AsyncFactory<T> = () => Promise<T> | T;
|
|
15
|
+
//# sourceMappingURL=utility.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utility.types.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/utility.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utility.types.js","sourceRoot":"","sources":["../../../src/domain/interfaces/utility.types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Worker, Job } from 'bullmq';
|
|
2
|
+
import { IWorkerConfig } from './config.interfaces';
|
|
3
|
+
/**
|
|
4
|
+
* Worker state tracking
|
|
5
|
+
*/
|
|
6
|
+
export interface IWorkerState {
|
|
7
|
+
workerId: string;
|
|
8
|
+
workerName: string;
|
|
9
|
+
nodeId: string;
|
|
10
|
+
entityId?: string;
|
|
11
|
+
entityType?: string;
|
|
12
|
+
status: 'starting' | 'ready' | 'processing' | 'closing' | 'closed';
|
|
13
|
+
createdAt: Date;
|
|
14
|
+
lastHeartbeat: Date;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Worker lifecycle events
|
|
18
|
+
*/
|
|
19
|
+
export interface IWorkerEvents {
|
|
20
|
+
onReady?: (worker: Worker, workerName: string) => void | Promise<void>;
|
|
21
|
+
onCompleted?: (job: Job, workerName: string) => void | Promise<void>;
|
|
22
|
+
onFailed?: (job: Job | undefined, error: Error, workerName: string) => void | Promise<void>;
|
|
23
|
+
onProgress?: (job: Job, progress: number | object) => void | Promise<void>;
|
|
24
|
+
onStalled?: (jobId: string, workerName: string) => void | Promise<void>;
|
|
25
|
+
onClosing?: (workerName: string) => void | Promise<void>;
|
|
26
|
+
onClosed?: (workerName: string) => void | Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Worker creation options
|
|
30
|
+
*/
|
|
31
|
+
export interface IWorkerCreationOptions {
|
|
32
|
+
workerName: string;
|
|
33
|
+
queueName: string;
|
|
34
|
+
config?: IWorkerConfig;
|
|
35
|
+
events?: IWorkerEvents;
|
|
36
|
+
processor: (job: Job) => Promise<unknown>;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Worker manager service interface
|
|
40
|
+
*/
|
|
41
|
+
export interface IWorkerManager {
|
|
42
|
+
/**
|
|
43
|
+
* Create a new worker with automatic lifecycle management
|
|
44
|
+
*/
|
|
45
|
+
createWorker(options: IWorkerCreationOptions): Promise<Worker>;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a worker exists and is alive (across ALL nodes)
|
|
48
|
+
*/
|
|
49
|
+
workerExists(workerName: string): Promise<boolean>;
|
|
50
|
+
/**
|
|
51
|
+
* Check if a worker exists on THIS node specifically
|
|
52
|
+
*/
|
|
53
|
+
workerExistsOnThisNode(workerName: string): Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* Get all running workers for current node
|
|
56
|
+
*/
|
|
57
|
+
getNodeWorkers(): Promise<string[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Get all running workers across all nodes
|
|
60
|
+
*/
|
|
61
|
+
getAllWorkers(): Promise<string[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Get all workers for a specific entity
|
|
64
|
+
*/
|
|
65
|
+
getEntityWorkers(entityType: string, entityId: string): Promise<string[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Signal a worker to close gracefully
|
|
68
|
+
*/
|
|
69
|
+
signalWorkerClose(workerName: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Signal all workers on current node to close
|
|
72
|
+
*/
|
|
73
|
+
signalNodeWorkersClose(): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Wait for all node workers to close
|
|
76
|
+
*/
|
|
77
|
+
waitForWorkersToClose(timeoutMs?: number): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Reset worker heartbeat TTL
|
|
80
|
+
*/
|
|
81
|
+
resetWorkerHeartbeat(workerName: string): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Remove worker heartbeat (mark as dead)
|
|
84
|
+
*/
|
|
85
|
+
removeWorkerHeartbeat(workerName: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Get the node ID for this instance
|
|
88
|
+
*/
|
|
89
|
+
getNodeId(): string;
|
|
90
|
+
/**
|
|
91
|
+
* Mark that a worker has completed a job (resets idle counter).
|
|
92
|
+
* Called internally when job completes.
|
|
93
|
+
*/
|
|
94
|
+
markWorkerActive(workerName: string): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get the idle seconds counter for a worker.
|
|
97
|
+
* This is incremented by the heartbeat and reset when a job completes.
|
|
98
|
+
*/
|
|
99
|
+
getWorkerIdleSeconds(workerName: string): Promise<number>;
|
|
100
|
+
/**
|
|
101
|
+
* Reset the idle counter for a worker (called when job completes).
|
|
102
|
+
*/
|
|
103
|
+
resetWorkerIdleCounter(workerName: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Increment the idle counter for a worker (called by heartbeat).
|
|
106
|
+
* Returns the new idle seconds value.
|
|
107
|
+
*/
|
|
108
|
+
incrementWorkerIdleCounter(workerName: string, incrementBy?: number): Promise<number>;
|
|
109
|
+
/**
|
|
110
|
+
* Remove the idle counter for a worker (cleanup).
|
|
111
|
+
*/
|
|
112
|
+
removeWorkerIdleCounter(workerName: string): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Check if a worker is idle based on threshold.
|
|
115
|
+
* @param workerName - Worker name
|
|
116
|
+
* @param thresholdSeconds - Idle threshold in seconds (default: 15)
|
|
117
|
+
*/
|
|
118
|
+
isWorkerIdle(workerName: string, thresholdSeconds?: number): Promise<boolean>;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=worker.interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.interfaces.d.ts","sourceRoot":"","sources":["../../../src/domain/interfaces/worker.interfaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.interfaces.js","sourceRoot":"","sources":["../../../src/domain/interfaces/worker.interfaces.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atomic-queues.module.d.ts","sourceRoot":"","sources":["../../src/module/atomic-queues.module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAIb,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,yBAAyB,EAAe,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"atomic-queues.module.d.ts","sourceRoot":"","sources":["../../src/module/atomic-queues.module.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EAIb,IAAI,EACL,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,yBAAyB,EAAe,MAAM,WAAW,CAAC;AA0BnE;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAE1B;;OAEG;IACH,UAAU,EAAE,CACV,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC;IAEpE;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,qBAEa,kBAAkB;IAC7B;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,yBAAyB,GAAG,aAAa;IA0BhE;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,8BAA8B,GAAG,aAAa;IAyB3E;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE;QACzB,UAAU,EAAE,MAAM,CAAC;QACnB,qBAAqB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7D,kBAAkB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5C,mBAAmB,CAAC,EAAE,MAAM,CAAC;KAC9B,GAAG,aAAa;IAgBjB;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAuBlC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,yBAAyB;IAUxC;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,wBAAwB;CAqBxC"}
|
|
@@ -29,10 +29,15 @@ const CORE_SERVICES = [
|
|
|
29
29
|
services_1.CronManagerService,
|
|
30
30
|
services_1.ServiceQueueManager,
|
|
31
31
|
services_1.ShutdownStateService,
|
|
32
|
+
services_1.ProcessorRegistry,
|
|
33
|
+
services_1.DecoratorDiscoveryService,
|
|
34
|
+
services_1.WorkerFactoryService,
|
|
35
|
+
services_1.ScalingRegistrationService,
|
|
32
36
|
services_1.ProcessorDiscoveryService,
|
|
33
37
|
services_1.CommandDiscoveryService,
|
|
34
38
|
services_1.QueueBus,
|
|
35
39
|
services_1.QueueEventsManagerService,
|
|
40
|
+
services_1.SpawnQueueService,
|
|
36
41
|
];
|
|
37
42
|
/**
|
|
38
43
|
* AtomicQueuesModule
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"atomic-queues.module.js","sourceRoot":"","sources":["../../src/module/atomic-queues.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAMwB;AACxB,uCAAkF;AAClF,sDAA4B;AAE5B,
|
|
1
|
+
{"version":3,"file":"atomic-queues.module.js","sourceRoot":"","sources":["../../src/module/atomic-queues.module.ts"],"names":[],"mappings":"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"}
|
|
@@ -152,6 +152,11 @@ export declare class CronManagerService implements ICronManager, OnModuleDestroy
|
|
|
152
152
|
* Workers increment idle counter on heartbeat, reset on job completion.
|
|
153
153
|
*/
|
|
154
154
|
private handleWorkerClosure;
|
|
155
|
+
/**
|
|
156
|
+
* Shared logic for terminating idle workers.
|
|
157
|
+
* Used by both handleIdleWorkersForActiveEntity and handleWorkerClosure.
|
|
158
|
+
*/
|
|
159
|
+
private terminateIdleWorkers;
|
|
155
160
|
/**
|
|
156
161
|
* Check if a queue has any waiting or active jobs.
|
|
157
162
|
* Uses BullMQ's internal key structure with the configured prefix.
|
|
@@ -190,9 +195,5 @@ export declare class CronManagerService implements ICronManager, OnModuleDestroy
|
|
|
190
195
|
* Determine the scaling action based on current vs desired.
|
|
191
196
|
*/
|
|
192
197
|
private determineAction;
|
|
193
|
-
/**
|
|
194
|
-
* Scan Redis keys matching a pattern.
|
|
195
|
-
*/
|
|
196
|
-
private scanKeys;
|
|
197
198
|
}
|
|
198
199
|
//# sourceMappingURL=cron-manager.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron-manager.service.d.ts","sourceRoot":"","sources":["../../../src/services/cron-manager/cron-manager.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,eAAe,EAAY,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"cron-manager.service.d.ts","sourceRoot":"","sources":["../../../src/services/cron-manager/cron-manager.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,eAAe,EAAY,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EAC1B,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAwB,MAAM,kBAAkB,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBACa,kBAAmB,YAAW,YAAY,EAAE,eAAe;IAUvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IAEnD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;IACjB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;IAdnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAgD;IAC9E,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAC1C,OAAO,CAAC,wBAAwB,CAAS;gBAGO,KAAK,EAAE,KAAK,EAEzC,MAAM,EAAE,yBAAyB,EACjC,aAAa,EAAE,oBAAoB,EACnC,YAAY,EAAE,mBAAmB,EACrB,mBAAmB,CAAC,EAAE,mBAAmB,YAAA;IAUxE;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAsB9B;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAKtD;;OAEG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAK9C;;;;;;;;;;;;;;;;;OAiBG;IACG,eAAe,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAepD;;;OAGG;YACW,uCAAuC;IAYrD;;OAEG;YACW,uBAAuB;IAoBrC;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IA8BjE;;OAEG;IACH,KAAK,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI;IA0BhC;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,eAAe,IAAI,IAAI;IAQvB;;;;;;;OAOG;YACW,6BAA6B;IAqF3C;;OAEG;YACW,oBAAoB;IA+ClC;;OAEG;YACW,mBAAmB;IAuCjC;;;;;OAKG;YACW,gCAAgC;IAQ9C;;;;OAIG;YACW,mBAAmB;IAQjC;;;OAGG;YACW,oBAAoB;IA0ElC;;;;;;;;;;;;OAYG;YACW,iBAAiB;IA8C/B;;OAEG;YACW,kBAAkB;IAqBhC;;OAEG;YACW,sBAAsB;IAapC;;;;OAIG;YACW,oBAAoB;IAYlC;;;;OAIG;YACW,sBAAsB;IAqBpC;;OAEG;IACH,OAAO,CAAC,eAAe;CASxB"}
|
|
@@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
19
19
|
exports.CronManagerService = void 0;
|
|
20
20
|
const common_1 = require("@nestjs/common");
|
|
21
21
|
const ioredis_1 = __importDefault(require("ioredis"));
|
|
22
|
+
const utils_1 = require("../../utils");
|
|
22
23
|
const constants_1 = require("../constants");
|
|
23
24
|
const worker_manager_1 = require("../worker-manager");
|
|
24
25
|
const index_manager_1 = require("../index-manager");
|
|
@@ -78,7 +79,7 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
78
79
|
this.cronInterval = null;
|
|
79
80
|
this.running = false;
|
|
80
81
|
this.scalingHandlerRegistered = false;
|
|
81
|
-
this.keyPrefix = config
|
|
82
|
+
this.keyPrefix = (0, utils_1.resolveKeyPrefix)(config);
|
|
82
83
|
// Use service queue for atomic operations if enabled
|
|
83
84
|
this.useServiceQueue = config.serviceQueue?.enabled !== false;
|
|
84
85
|
// Register the scaling cycle handler with the service queue
|
|
@@ -381,43 +382,7 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
381
382
|
* on the next scaling cycle if the entity is still active.
|
|
382
383
|
*/
|
|
383
384
|
async handleIdleWorkersForActiveEntity(entityType, entityId, config) {
|
|
384
|
-
|
|
385
|
-
if (workers.length === 0) {
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
// Get idle timeout threshold (default: 15 seconds)
|
|
389
|
-
const idleTimeoutSeconds = config.idleTimeoutSeconds ?? 15;
|
|
390
|
-
// Check each worker's idle time
|
|
391
|
-
const idleWorkers = [];
|
|
392
|
-
for (const workerName of workers) {
|
|
393
|
-
const isIdle = await this.workerManager.isWorkerIdle(workerName, idleTimeoutSeconds);
|
|
394
|
-
if (isIdle) {
|
|
395
|
-
idleWorkers.push(workerName);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
if (idleWorkers.length === 0) {
|
|
399
|
-
return null;
|
|
400
|
-
}
|
|
401
|
-
this.logger.log(`[handleIdleWorkers] Terminating ${idleWorkers.length} idle workers for active ${entityType}/${entityId} (idle >= ${idleTimeoutSeconds}s)`);
|
|
402
|
-
// Signal idle workers to close
|
|
403
|
-
for (const workerName of idleWorkers) {
|
|
404
|
-
const idleSeconds = await this.workerManager.getWorkerIdleSeconds(workerName);
|
|
405
|
-
this.logger.debug(`[handleIdleWorkers] Terminating idle worker: ${workerName} (idle: ${idleSeconds}s)`);
|
|
406
|
-
if (config.onTerminateWorker) {
|
|
407
|
-
await config.onTerminateWorker(entityId, workerName);
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
await this.workerManager.signalWorkerClose(workerName);
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
return {
|
|
414
|
-
entityId,
|
|
415
|
-
entityType,
|
|
416
|
-
currentWorkers: workers.length,
|
|
417
|
-
desiredWorkers: workers.length - idleWorkers.length,
|
|
418
|
-
action: 'terminate',
|
|
419
|
-
count: idleWorkers.length,
|
|
420
|
-
};
|
|
385
|
+
return this.terminateIdleWorkers(entityType, entityId, config, 'active-entity');
|
|
421
386
|
}
|
|
422
387
|
/**
|
|
423
388
|
* Handle worker closure for entities with no jobs.
|
|
@@ -425,12 +390,24 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
425
390
|
* Workers increment idle counter on heartbeat, reset on job completion.
|
|
426
391
|
*/
|
|
427
392
|
async handleWorkerClosure(entityType, entityId, config) {
|
|
393
|
+
return this.terminateIdleWorkers(entityType, entityId, config, 'orphaned-entity');
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Shared logic for terminating idle workers.
|
|
397
|
+
* Used by both handleIdleWorkersForActiveEntity and handleWorkerClosure.
|
|
398
|
+
*/
|
|
399
|
+
async terminateIdleWorkers(entityType, entityId, config, context) {
|
|
400
|
+
const logTag = context === 'active-entity' ? 'handleIdleWorkers' : 'handleWorkerClosure';
|
|
428
401
|
const workers = await this.workerManager.getEntityWorkers(entityType, entityId);
|
|
429
402
|
if (workers.length === 0) {
|
|
430
|
-
|
|
403
|
+
if (context === 'orphaned-entity') {
|
|
404
|
+
this.logger.debug(`[${logTag}] ${entityType}/${entityId} - No workers found, skipping`);
|
|
405
|
+
}
|
|
431
406
|
return null;
|
|
432
407
|
}
|
|
433
|
-
|
|
408
|
+
if (context === 'orphaned-entity') {
|
|
409
|
+
this.logger.debug(`[${logTag}] ${entityType}/${entityId} - Found ${workers.length} workers to potentially close: ${workers.join(', ')}`);
|
|
410
|
+
}
|
|
434
411
|
// Get idle timeout threshold (default: 15 seconds)
|
|
435
412
|
const idleTimeoutSeconds = config.idleTimeoutSeconds ?? 15;
|
|
436
413
|
// Check each worker's idle time
|
|
@@ -442,14 +419,19 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
442
419
|
}
|
|
443
420
|
}
|
|
444
421
|
if (idleWorkers.length === 0) {
|
|
445
|
-
|
|
422
|
+
if (context === 'orphaned-entity') {
|
|
423
|
+
this.logger.debug(`[${logTag}] ${entityType}/${entityId} - No idle workers (threshold: ${idleTimeoutSeconds}s), skipping termination`);
|
|
424
|
+
}
|
|
446
425
|
return null;
|
|
447
426
|
}
|
|
448
|
-
|
|
427
|
+
const actionLabel = context === 'active-entity'
|
|
428
|
+
? `Terminating ${idleWorkers.length} idle workers for active ${entityType}/${entityId}`
|
|
429
|
+
: `Closing ${idleWorkers.length} idle workers for ${entityType}/${entityId}`;
|
|
430
|
+
this.logger.log(`[${logTag}] ${actionLabel} (idle >= ${idleTimeoutSeconds}s)`);
|
|
449
431
|
// Signal idle workers to close
|
|
450
432
|
for (const workerName of idleWorkers) {
|
|
451
433
|
const idleSeconds = await this.workerManager.getWorkerIdleSeconds(workerName);
|
|
452
|
-
this.logger.debug(`[
|
|
434
|
+
this.logger.debug(`[${logTag}] Terminating worker: ${workerName} (idle: ${idleSeconds}s)`);
|
|
453
435
|
if (config.onTerminateWorker) {
|
|
454
436
|
await config.onTerminateWorker(entityId, workerName);
|
|
455
437
|
}
|
|
@@ -562,7 +544,7 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
562
544
|
async getEntitiesWithWorkers(entityType) {
|
|
563
545
|
// Worker heartbeat keys follow pattern: {prefix}:worker:{nodeId}:{entityId}-worker
|
|
564
546
|
const pattern = `${this.keyPrefix}:worker:*:*-worker`;
|
|
565
|
-
const keys = await
|
|
547
|
+
const keys = await (0, utils_1.scanKeys)(this.redis, pattern);
|
|
566
548
|
const entities = new Set();
|
|
567
549
|
for (const key of keys) {
|
|
568
550
|
const parts = key.split(':');
|
|
@@ -587,19 +569,6 @@ let CronManagerService = CronManagerService_1 = class CronManagerService {
|
|
|
587
569
|
return 'terminate';
|
|
588
570
|
return 'none';
|
|
589
571
|
}
|
|
590
|
-
/**
|
|
591
|
-
* Scan Redis keys matching a pattern.
|
|
592
|
-
*/
|
|
593
|
-
async scanKeys(pattern) {
|
|
594
|
-
let cursor = '0';
|
|
595
|
-
const keys = [];
|
|
596
|
-
do {
|
|
597
|
-
const [nextCursor, scanKeys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);
|
|
598
|
-
cursor = nextCursor;
|
|
599
|
-
keys.push(...scanKeys);
|
|
600
|
-
} while (cursor !== '0');
|
|
601
|
-
return keys;
|
|
602
|
-
}
|
|
603
572
|
};
|
|
604
573
|
exports.CronManagerService = CronManagerService;
|
|
605
574
|
exports.CronManagerService = CronManagerService = CronManagerService_1 = __decorate([
|