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.
- package/README.md +686 -0
- package/dist/decorators/decorators.d.ts +67 -0
- package/dist/decorators/decorators.d.ts.map +1 -0
- package/dist/decorators/decorators.js +91 -0
- package/dist/decorators/decorators.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +18 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/domain/index.d.ts +5 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +21 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/interfaces.d.ts +614 -0
- package/dist/domain/interfaces.d.ts.map +1 -0
- package/dist/domain/interfaces.js +19 -0
- package/dist/domain/interfaces.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/module/atomic-queues.module.d.ts +97 -0
- package/dist/module/atomic-queues.module.d.ts.map +1 -0
- package/dist/module/atomic-queues.module.js +197 -0
- package/dist/module/atomic-queues.module.js.map +1 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.d.ts.map +1 -0
- package/dist/module/index.js +18 -0
- package/dist/module/index.js.map +1 -0
- package/dist/services/constants.d.ts +10 -0
- package/dist/services/constants.d.ts.map +1 -0
- package/dist/services/constants.js +13 -0
- package/dist/services/constants.js.map +1 -0
- package/dist/services/cron-manager/cron-manager.service.d.ts +188 -0
- package/dist/services/cron-manager/cron-manager.service.d.ts.map +1 -0
- package/dist/services/cron-manager/cron-manager.service.js +534 -0
- package/dist/services/cron-manager/cron-manager.service.js.map +1 -0
- package/dist/services/cron-manager/index.d.ts +2 -0
- package/dist/services/cron-manager/index.d.ts.map +1 -0
- package/dist/services/cron-manager/index.js +18 -0
- package/dist/services/cron-manager/index.js.map +1 -0
- package/dist/services/index-manager/index-manager.service.d.ts +146 -0
- package/dist/services/index-manager/index-manager.service.d.ts.map +1 -0
- package/dist/services/index-manager/index-manager.service.js +337 -0
- package/dist/services/index-manager/index-manager.service.js.map +1 -0
- package/dist/services/index-manager/index.d.ts +2 -0
- package/dist/services/index-manager/index.d.ts.map +1 -0
- package/dist/services/index-manager/index.js +18 -0
- package/dist/services/index-manager/index.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +26 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/job-processor/index.d.ts +2 -0
- package/dist/services/job-processor/index.d.ts.map +1 -0
- package/dist/services/job-processor/index.js +18 -0
- package/dist/services/job-processor/index.js.map +1 -0
- package/dist/services/job-processor/job-processor.service.d.ts +156 -0
- package/dist/services/job-processor/job-processor.service.d.ts.map +1 -0
- package/dist/services/job-processor/job-processor.service.js +331 -0
- package/dist/services/job-processor/job-processor.service.js.map +1 -0
- package/dist/services/queue-manager/index.d.ts +2 -0
- package/dist/services/queue-manager/index.d.ts.map +1 -0
- package/dist/services/queue-manager/index.js +18 -0
- package/dist/services/queue-manager/index.js.map +1 -0
- package/dist/services/queue-manager/queue-manager.service.d.ts +128 -0
- package/dist/services/queue-manager/queue-manager.service.d.ts.map +1 -0
- package/dist/services/queue-manager/queue-manager.service.js +308 -0
- package/dist/services/queue-manager/queue-manager.service.js.map +1 -0
- package/dist/services/resource-lock/index.d.ts +2 -0
- package/dist/services/resource-lock/index.d.ts.map +1 -0
- package/dist/services/resource-lock/index.js +18 -0
- package/dist/services/resource-lock/index.js.map +1 -0
- package/dist/services/resource-lock/resource-lock.service.d.ts +124 -0
- package/dist/services/resource-lock/resource-lock.service.d.ts.map +1 -0
- package/dist/services/resource-lock/resource-lock.service.js +379 -0
- package/dist/services/resource-lock/resource-lock.service.js.map +1 -0
- package/dist/services/service-queue/index.d.ts +2 -0
- package/dist/services/service-queue/index.d.ts.map +1 -0
- package/dist/services/service-queue/index.js +18 -0
- package/dist/services/service-queue/index.js.map +1 -0
- package/dist/services/service-queue/service-queue.service.d.ts +232 -0
- package/dist/services/service-queue/service-queue.service.d.ts.map +1 -0
- package/dist/services/service-queue/service-queue.service.js +647 -0
- package/dist/services/service-queue/service-queue.service.js.map +1 -0
- package/dist/services/shutdown-state/index.d.ts +2 -0
- package/dist/services/shutdown-state/index.d.ts.map +1 -0
- package/dist/services/shutdown-state/index.js +18 -0
- package/dist/services/shutdown-state/index.js.map +1 -0
- package/dist/services/shutdown-state/shutdown-state.service.d.ts +69 -0
- package/dist/services/shutdown-state/shutdown-state.service.d.ts.map +1 -0
- package/dist/services/shutdown-state/shutdown-state.service.js +127 -0
- package/dist/services/shutdown-state/shutdown-state.service.js.map +1 -0
- package/dist/services/worker-manager/index.d.ts +2 -0
- package/dist/services/worker-manager/index.d.ts.map +1 -0
- package/dist/services/worker-manager/index.js +18 -0
- package/dist/services/worker-manager/index.js.map +1 -0
- package/dist/services/worker-manager/worker-manager.service.d.ts +163 -0
- package/dist/services/worker-manager/worker-manager.service.d.ts.map +1 -0
- package/dist/services/worker-manager/worker-manager.service.js +460 -0
- package/dist/services/worker-manager/worker-manager.service.js.map +1 -0
- package/dist/utils/helpers.d.ts +124 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +229 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +18 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { CommandBus, QueryBus } from '@nestjs/cqrs';
|
|
2
|
+
import { Job } from 'bullmq';
|
|
3
|
+
import { IJobProcessorRegistry, IAtomicJobData, IJobResult, IDynamicExecutor, JobProcessor, Constructor } from '../../domain';
|
|
4
|
+
import { IAtomicQueuesModuleConfig } from '../../domain';
|
|
5
|
+
/**
|
|
6
|
+
* JobProcessorRegistry
|
|
7
|
+
*
|
|
8
|
+
* Registry for job processors that can be looked up by job type.
|
|
9
|
+
* Supports both custom processors and CQRS command/query execution.
|
|
10
|
+
*/
|
|
11
|
+
export declare class JobProcessorRegistry implements IJobProcessorRegistry {
|
|
12
|
+
private readonly logger;
|
|
13
|
+
private readonly processors;
|
|
14
|
+
/**
|
|
15
|
+
* Register a processor for a job type.
|
|
16
|
+
*/
|
|
17
|
+
registerProcessor<T, R>(jobType: string, processor: JobProcessor<T, R>): void;
|
|
18
|
+
/**
|
|
19
|
+
* Get processor for a job type.
|
|
20
|
+
*/
|
|
21
|
+
getProcessor<T, R>(jobType: string): JobProcessor<T, R> | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Check if processor exists.
|
|
24
|
+
*/
|
|
25
|
+
hasProcessor(jobType: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Get all registered job types.
|
|
28
|
+
*/
|
|
29
|
+
getRegisteredTypes(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Unregister a processor.
|
|
32
|
+
*/
|
|
33
|
+
unregisterProcessor(jobType: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Clear all processors.
|
|
36
|
+
*/
|
|
37
|
+
clearAll(): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* DynamicExecutorService
|
|
41
|
+
*
|
|
42
|
+
* Executes commands and queries dynamically by class name.
|
|
43
|
+
* This is the pattern used by bl-blackjack-service for the ServiceAtomicProcessor.
|
|
44
|
+
*
|
|
45
|
+
* Key Features:
|
|
46
|
+
* - Dynamic module loading for commands/queries
|
|
47
|
+
* - Uses class-transformer to instantiate payloads
|
|
48
|
+
* - Supports both CommandBus and QueryBus execution
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* // Register modules
|
|
53
|
+
* executor.registerCommandModule('../application/commands');
|
|
54
|
+
* executor.registerQueryModule('../application/queries');
|
|
55
|
+
*
|
|
56
|
+
* // Execute dynamically
|
|
57
|
+
* const result = await executor.executeCommand('MakeBetCommand', { amount: 100 });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare class DynamicExecutorService implements IDynamicExecutor {
|
|
61
|
+
private readonly commandBus;
|
|
62
|
+
private readonly queryBus;
|
|
63
|
+
private readonly logger;
|
|
64
|
+
private readonly commandModules;
|
|
65
|
+
private readonly queryModules;
|
|
66
|
+
private readonly cachedCommandClasses;
|
|
67
|
+
private readonly cachedQueryClasses;
|
|
68
|
+
constructor(commandBus: CommandBus, queryBus: QueryBus);
|
|
69
|
+
/**
|
|
70
|
+
* Execute a command by class name.
|
|
71
|
+
*/
|
|
72
|
+
executeCommand<T>(commandName: string, payload: T): Promise<unknown>;
|
|
73
|
+
/**
|
|
74
|
+
* Execute a query by class name.
|
|
75
|
+
*/
|
|
76
|
+
executeQuery<T>(queryName: string, payload: T): Promise<unknown>;
|
|
77
|
+
/**
|
|
78
|
+
* Register command module for dynamic loading.
|
|
79
|
+
*/
|
|
80
|
+
registerCommandModule(modulePath: string): void;
|
|
81
|
+
/**
|
|
82
|
+
* Register query module for dynamic loading.
|
|
83
|
+
*/
|
|
84
|
+
registerQueryModule(modulePath: string): void;
|
|
85
|
+
/**
|
|
86
|
+
* Pre-register a command class directly (preferred method).
|
|
87
|
+
*/
|
|
88
|
+
registerCommandClass(name: string, commandClass: Constructor): void;
|
|
89
|
+
/**
|
|
90
|
+
* Pre-register a query class directly (preferred method).
|
|
91
|
+
*/
|
|
92
|
+
registerQueryClass(name: string, queryClass: Constructor): void;
|
|
93
|
+
/**
|
|
94
|
+
* Bulk register command classes.
|
|
95
|
+
*/
|
|
96
|
+
registerCommandClasses(classes: Record<string, Constructor>): void;
|
|
97
|
+
/**
|
|
98
|
+
* Bulk register query classes.
|
|
99
|
+
*/
|
|
100
|
+
registerQueryClasses(classes: Record<string, Constructor>): void;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve a command class by name.
|
|
103
|
+
*/
|
|
104
|
+
private resolveCommandClass;
|
|
105
|
+
/**
|
|
106
|
+
* Resolve a query class by name.
|
|
107
|
+
*/
|
|
108
|
+
private resolveQueryClass;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* AtomicJobProcessor
|
|
112
|
+
*
|
|
113
|
+
* Main job processor service that combines the registry and dynamic executor
|
|
114
|
+
* to process atomic jobs with support for:
|
|
115
|
+
*
|
|
116
|
+
* 1. Custom registered processors
|
|
117
|
+
* 2. Dynamic CQRS command/query execution
|
|
118
|
+
* 3. Job progress tracking
|
|
119
|
+
* 4. Error handling and result capture
|
|
120
|
+
*
|
|
121
|
+
* This is the unified processor that should be used by workers.
|
|
122
|
+
*/
|
|
123
|
+
export declare class AtomicJobProcessor {
|
|
124
|
+
private readonly registry;
|
|
125
|
+
private readonly executor;
|
|
126
|
+
private readonly config;
|
|
127
|
+
private readonly logger;
|
|
128
|
+
constructor(registry: JobProcessorRegistry, executor: DynamicExecutorService, config: IAtomicQueuesModuleConfig);
|
|
129
|
+
/**
|
|
130
|
+
* Process an atomic job.
|
|
131
|
+
*
|
|
132
|
+
* Processing order:
|
|
133
|
+
* 1. Check for custom registered processor
|
|
134
|
+
* 2. If type is 'command', use dynamic executor
|
|
135
|
+
* 3. If type is 'query', use dynamic executor
|
|
136
|
+
* 4. If type is 'custom', use registered processor only
|
|
137
|
+
*/
|
|
138
|
+
process<T = unknown, R = unknown>(job: Job<IAtomicJobData<T>>): Promise<IJobResult<R>>;
|
|
139
|
+
/**
|
|
140
|
+
* Create a processor function for use with WorkerManager.createWorker().
|
|
141
|
+
*/
|
|
142
|
+
createProcessor<T = unknown, R = unknown>(): (job: Job<IAtomicJobData<T>>) => Promise<R | undefined>;
|
|
143
|
+
/**
|
|
144
|
+
* Register a custom processor.
|
|
145
|
+
*/
|
|
146
|
+
registerProcessor<T, R>(jobType: string, processor: JobProcessor<T, R>): void;
|
|
147
|
+
/**
|
|
148
|
+
* Register command classes for dynamic execution.
|
|
149
|
+
*/
|
|
150
|
+
registerCommands(classes: Record<string, Constructor>): void;
|
|
151
|
+
/**
|
|
152
|
+
* Register query classes for dynamic execution.
|
|
153
|
+
*/
|
|
154
|
+
registerQueries(classes: Record<string, Constructor>): void;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=job-processor.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-processor.service.d.ts","sourceRoot":"","sources":["../../../src/services/job-processor/job-processor.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,331 @@
|
|
|
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 JobProcessorRegistry_1, DynamicExecutorService_1, AtomicJobProcessor_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.AtomicJobProcessor = exports.DynamicExecutorService = exports.JobProcessorRegistry = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const cqrs_1 = require("@nestjs/cqrs");
|
|
19
|
+
const class_transformer_1 = require("class-transformer");
|
|
20
|
+
const constants_1 = require("../constants");
|
|
21
|
+
/**
|
|
22
|
+
* JobProcessorRegistry
|
|
23
|
+
*
|
|
24
|
+
* Registry for job processors that can be looked up by job type.
|
|
25
|
+
* Supports both custom processors and CQRS command/query execution.
|
|
26
|
+
*/
|
|
27
|
+
let JobProcessorRegistry = JobProcessorRegistry_1 = class JobProcessorRegistry {
|
|
28
|
+
constructor() {
|
|
29
|
+
this.logger = new common_1.Logger(JobProcessorRegistry_1.name);
|
|
30
|
+
this.processors = new Map();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Register a processor for a job type.
|
|
34
|
+
*/
|
|
35
|
+
registerProcessor(jobType, processor) {
|
|
36
|
+
this.processors.set(jobType, processor);
|
|
37
|
+
this.logger.debug(`Registered processor for job type: ${jobType}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get processor for a job type.
|
|
41
|
+
*/
|
|
42
|
+
getProcessor(jobType) {
|
|
43
|
+
return this.processors.get(jobType);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if processor exists.
|
|
47
|
+
*/
|
|
48
|
+
hasProcessor(jobType) {
|
|
49
|
+
return this.processors.has(jobType);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get all registered job types.
|
|
53
|
+
*/
|
|
54
|
+
getRegisteredTypes() {
|
|
55
|
+
return Array.from(this.processors.keys());
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Unregister a processor.
|
|
59
|
+
*/
|
|
60
|
+
unregisterProcessor(jobType) {
|
|
61
|
+
return this.processors.delete(jobType);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Clear all processors.
|
|
65
|
+
*/
|
|
66
|
+
clearAll() {
|
|
67
|
+
this.processors.clear();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
exports.JobProcessorRegistry = JobProcessorRegistry;
|
|
71
|
+
exports.JobProcessorRegistry = JobProcessorRegistry = JobProcessorRegistry_1 = __decorate([
|
|
72
|
+
(0, common_1.Injectable)()
|
|
73
|
+
], JobProcessorRegistry);
|
|
74
|
+
/**
|
|
75
|
+
* DynamicExecutorService
|
|
76
|
+
*
|
|
77
|
+
* Executes commands and queries dynamically by class name.
|
|
78
|
+
* This is the pattern used by bl-blackjack-service for the ServiceAtomicProcessor.
|
|
79
|
+
*
|
|
80
|
+
* Key Features:
|
|
81
|
+
* - Dynamic module loading for commands/queries
|
|
82
|
+
* - Uses class-transformer to instantiate payloads
|
|
83
|
+
* - Supports both CommandBus and QueryBus execution
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* // Register modules
|
|
88
|
+
* executor.registerCommandModule('../application/commands');
|
|
89
|
+
* executor.registerQueryModule('../application/queries');
|
|
90
|
+
*
|
|
91
|
+
* // Execute dynamically
|
|
92
|
+
* const result = await executor.executeCommand('MakeBetCommand', { amount: 100 });
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
let DynamicExecutorService = DynamicExecutorService_1 = class DynamicExecutorService {
|
|
96
|
+
constructor(commandBus, queryBus) {
|
|
97
|
+
this.commandBus = commandBus;
|
|
98
|
+
this.queryBus = queryBus;
|
|
99
|
+
this.logger = new common_1.Logger(DynamicExecutorService_1.name);
|
|
100
|
+
this.commandModules = new Map();
|
|
101
|
+
this.queryModules = new Map();
|
|
102
|
+
this.cachedCommandClasses = new Map();
|
|
103
|
+
this.cachedQueryClasses = new Map();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Execute a command by class name.
|
|
107
|
+
*/
|
|
108
|
+
async executeCommand(commandName, payload) {
|
|
109
|
+
const CommandClass = await this.resolveCommandClass(commandName);
|
|
110
|
+
if (!CommandClass) {
|
|
111
|
+
throw new Error(`Command class not found: ${commandName}`);
|
|
112
|
+
}
|
|
113
|
+
const commandInstance = (0, class_transformer_1.plainToInstance)(CommandClass, payload);
|
|
114
|
+
this.logger.debug(`Executing command: ${commandName}`);
|
|
115
|
+
return this.commandBus.execute(commandInstance);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Execute a query by class name.
|
|
119
|
+
*/
|
|
120
|
+
async executeQuery(queryName, payload) {
|
|
121
|
+
const QueryClass = await this.resolveQueryClass(queryName);
|
|
122
|
+
if (!QueryClass) {
|
|
123
|
+
throw new Error(`Query class not found: ${queryName}`);
|
|
124
|
+
}
|
|
125
|
+
const queryInstance = (0, class_transformer_1.plainToInstance)(QueryClass, payload);
|
|
126
|
+
this.logger.debug(`Executing query: ${queryName}`);
|
|
127
|
+
return this.queryBus.execute(queryInstance);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Register command module for dynamic loading.
|
|
131
|
+
*/
|
|
132
|
+
registerCommandModule(modulePath) {
|
|
133
|
+
this.logger.debug(`Registered command module path: ${modulePath}`);
|
|
134
|
+
// Module will be loaded on-demand when needed
|
|
135
|
+
// Store path for later dynamic import
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Register query module for dynamic loading.
|
|
139
|
+
*/
|
|
140
|
+
registerQueryModule(modulePath) {
|
|
141
|
+
this.logger.debug(`Registered query module path: ${modulePath}`);
|
|
142
|
+
// Module will be loaded on-demand when needed
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Pre-register a command class directly (preferred method).
|
|
146
|
+
*/
|
|
147
|
+
registerCommandClass(name, commandClass) {
|
|
148
|
+
this.cachedCommandClasses.set(name, commandClass);
|
|
149
|
+
this.logger.debug(`Pre-registered command class: ${name}`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Pre-register a query class directly (preferred method).
|
|
153
|
+
*/
|
|
154
|
+
registerQueryClass(name, queryClass) {
|
|
155
|
+
this.cachedQueryClasses.set(name, queryClass);
|
|
156
|
+
this.logger.debug(`Pre-registered query class: ${name}`);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Bulk register command classes.
|
|
160
|
+
*/
|
|
161
|
+
registerCommandClasses(classes) {
|
|
162
|
+
for (const [name, cls] of Object.entries(classes)) {
|
|
163
|
+
this.cachedCommandClasses.set(name, cls);
|
|
164
|
+
}
|
|
165
|
+
this.logger.debug(`Bulk registered ${Object.keys(classes).length} command classes`);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Bulk register query classes.
|
|
169
|
+
*/
|
|
170
|
+
registerQueryClasses(classes) {
|
|
171
|
+
for (const [name, cls] of Object.entries(classes)) {
|
|
172
|
+
this.cachedQueryClasses.set(name, cls);
|
|
173
|
+
}
|
|
174
|
+
this.logger.debug(`Bulk registered ${Object.keys(classes).length} query classes`);
|
|
175
|
+
}
|
|
176
|
+
// =========================================================================
|
|
177
|
+
// PRIVATE METHODS
|
|
178
|
+
// =========================================================================
|
|
179
|
+
/**
|
|
180
|
+
* Resolve a command class by name.
|
|
181
|
+
*/
|
|
182
|
+
async resolveCommandClass(commandName) {
|
|
183
|
+
// First check cache
|
|
184
|
+
if (this.cachedCommandClasses.has(commandName)) {
|
|
185
|
+
return this.cachedCommandClasses.get(commandName);
|
|
186
|
+
}
|
|
187
|
+
// If not cached, check loaded modules
|
|
188
|
+
for (const module of this.commandModules.values()) {
|
|
189
|
+
if (module[commandName]) {
|
|
190
|
+
this.cachedCommandClasses.set(commandName, module[commandName]);
|
|
191
|
+
return module[commandName];
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Resolve a query class by name.
|
|
198
|
+
*/
|
|
199
|
+
async resolveQueryClass(queryName) {
|
|
200
|
+
// First check cache
|
|
201
|
+
if (this.cachedQueryClasses.has(queryName)) {
|
|
202
|
+
return this.cachedQueryClasses.get(queryName);
|
|
203
|
+
}
|
|
204
|
+
// If not cached, check loaded modules
|
|
205
|
+
for (const module of this.queryModules.values()) {
|
|
206
|
+
if (module[queryName]) {
|
|
207
|
+
this.cachedQueryClasses.set(queryName, module[queryName]);
|
|
208
|
+
return module[queryName];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return undefined;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
exports.DynamicExecutorService = DynamicExecutorService;
|
|
215
|
+
exports.DynamicExecutorService = DynamicExecutorService = DynamicExecutorService_1 = __decorate([
|
|
216
|
+
(0, common_1.Injectable)(),
|
|
217
|
+
__param(0, (0, common_1.Optional)()),
|
|
218
|
+
__param(1, (0, common_1.Optional)()),
|
|
219
|
+
__metadata("design:paramtypes", [cqrs_1.CommandBus,
|
|
220
|
+
cqrs_1.QueryBus])
|
|
221
|
+
], DynamicExecutorService);
|
|
222
|
+
/**
|
|
223
|
+
* AtomicJobProcessor
|
|
224
|
+
*
|
|
225
|
+
* Main job processor service that combines the registry and dynamic executor
|
|
226
|
+
* to process atomic jobs with support for:
|
|
227
|
+
*
|
|
228
|
+
* 1. Custom registered processors
|
|
229
|
+
* 2. Dynamic CQRS command/query execution
|
|
230
|
+
* 3. Job progress tracking
|
|
231
|
+
* 4. Error handling and result capture
|
|
232
|
+
*
|
|
233
|
+
* This is the unified processor that should be used by workers.
|
|
234
|
+
*/
|
|
235
|
+
let AtomicJobProcessor = AtomicJobProcessor_1 = class AtomicJobProcessor {
|
|
236
|
+
constructor(registry, executor, config) {
|
|
237
|
+
this.registry = registry;
|
|
238
|
+
this.executor = executor;
|
|
239
|
+
this.config = config;
|
|
240
|
+
this.logger = new common_1.Logger(AtomicJobProcessor_1.name);
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Process an atomic job.
|
|
244
|
+
*
|
|
245
|
+
* Processing order:
|
|
246
|
+
* 1. Check for custom registered processor
|
|
247
|
+
* 2. If type is 'command', use dynamic executor
|
|
248
|
+
* 3. If type is 'query', use dynamic executor
|
|
249
|
+
* 4. If type is 'custom', use registered processor only
|
|
250
|
+
*/
|
|
251
|
+
async process(job) {
|
|
252
|
+
const startTime = Date.now();
|
|
253
|
+
const { data } = job;
|
|
254
|
+
const { type, commandName } = data;
|
|
255
|
+
this.logger.debug(`Processing job ${job.id}: type=${type}, command=${commandName}`);
|
|
256
|
+
try {
|
|
257
|
+
let result;
|
|
258
|
+
// Check for custom processor first
|
|
259
|
+
if (this.registry.hasProcessor(job.name)) {
|
|
260
|
+
const processor = this.registry.getProcessor(job.name);
|
|
261
|
+
result = await processor(job);
|
|
262
|
+
}
|
|
263
|
+
// Dynamic command execution
|
|
264
|
+
else if (type === 'command' && commandName) {
|
|
265
|
+
result = (await this.executor.executeCommand(commandName, data.payload));
|
|
266
|
+
}
|
|
267
|
+
// Dynamic query execution
|
|
268
|
+
else if (type === 'query' && commandName) {
|
|
269
|
+
result = (await this.executor.executeQuery(commandName, data.payload));
|
|
270
|
+
}
|
|
271
|
+
// Unknown type
|
|
272
|
+
else {
|
|
273
|
+
throw new Error(`Unknown job type or missing processor: ${type}/${job.name}`);
|
|
274
|
+
}
|
|
275
|
+
const processingTime = Date.now() - startTime;
|
|
276
|
+
this.logger.debug(`Job ${job.id} completed in ${processingTime}ms`);
|
|
277
|
+
return {
|
|
278
|
+
success: true,
|
|
279
|
+
result,
|
|
280
|
+
processingTime,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
catch (error) {
|
|
284
|
+
const processingTime = Date.now() - startTime;
|
|
285
|
+
this.logger.error(`Job ${job.id} failed: ${error.message}`);
|
|
286
|
+
return {
|
|
287
|
+
success: false,
|
|
288
|
+
error: error.message,
|
|
289
|
+
processingTime,
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Create a processor function for use with WorkerManager.createWorker().
|
|
295
|
+
*/
|
|
296
|
+
createProcessor() {
|
|
297
|
+
return async (job) => {
|
|
298
|
+
const result = await this.process(job);
|
|
299
|
+
if (!result.success) {
|
|
300
|
+
throw new Error(result.error);
|
|
301
|
+
}
|
|
302
|
+
return result.result;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Register a custom processor.
|
|
307
|
+
*/
|
|
308
|
+
registerProcessor(jobType, processor) {
|
|
309
|
+
this.registry.registerProcessor(jobType, processor);
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Register command classes for dynamic execution.
|
|
313
|
+
*/
|
|
314
|
+
registerCommands(classes) {
|
|
315
|
+
this.executor.registerCommandClasses(classes);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Register query classes for dynamic execution.
|
|
319
|
+
*/
|
|
320
|
+
registerQueries(classes) {
|
|
321
|
+
this.executor.registerQueryClasses(classes);
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
exports.AtomicJobProcessor = AtomicJobProcessor;
|
|
325
|
+
exports.AtomicJobProcessor = AtomicJobProcessor = AtomicJobProcessor_1 = __decorate([
|
|
326
|
+
(0, common_1.Injectable)(),
|
|
327
|
+
__param(2, (0, common_1.Inject)(constants_1.ATOMIC_QUEUES_CONFIG)),
|
|
328
|
+
__metadata("design:paramtypes", [JobProcessorRegistry,
|
|
329
|
+
DynamicExecutorService, Object])
|
|
330
|
+
], AtomicJobProcessor);
|
|
331
|
+
//# sourceMappingURL=job-processor.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-processor.service.js","sourceRoot":"","sources":["../../../src/services/job-processor/job-processor.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/queue-manager/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,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("./queue-manager.service"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/queue-manager/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0DAAwC"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
import { Queue, Job } from 'bullmq';
|
|
3
|
+
import Redis from 'ioredis';
|
|
4
|
+
import { IQueueManager, IManagedQueue, IJobOptions } from '../../domain';
|
|
5
|
+
import { IAtomicQueuesModuleConfig } from '../../domain';
|
|
6
|
+
/**
|
|
7
|
+
* QueueManagerService
|
|
8
|
+
*
|
|
9
|
+
* Manages dynamic queue creation and destruction per entity.
|
|
10
|
+
* This is the core service for creating queues on-demand for users, tables,
|
|
11
|
+
* or any other entity type that requires atomic processing.
|
|
12
|
+
*
|
|
13
|
+
* Key Features:
|
|
14
|
+
* - Dynamic queue creation with lazy initialization
|
|
15
|
+
* - Entity-specific queue naming conventions
|
|
16
|
+
* - Automatic cleanup on module destroy
|
|
17
|
+
* - Job management (add, delete)
|
|
18
|
+
* - Queue lifecycle management
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* // Get or create a queue for a user
|
|
23
|
+
* const queue = queueManager.getOrCreateEntityQueue('user', '123');
|
|
24
|
+
*
|
|
25
|
+
* // Add a job to the queue
|
|
26
|
+
* await queueManager.addJob('user-123-queue', 'process-message', { text: 'hello' });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class QueueManagerService implements IQueueManager, OnModuleDestroy {
|
|
30
|
+
private readonly redis;
|
|
31
|
+
private readonly config;
|
|
32
|
+
private readonly logger;
|
|
33
|
+
private readonly queues;
|
|
34
|
+
private readonly keyPrefix;
|
|
35
|
+
constructor(redis: Redis, config: IAtomicQueuesModuleConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Get or create a queue by name.
|
|
38
|
+
* If the queue doesn't exist, it will be created with default configuration.
|
|
39
|
+
*/
|
|
40
|
+
getOrCreateQueue(queueName: string): Queue;
|
|
41
|
+
/**
|
|
42
|
+
* Get or create an entity-specific queue.
|
|
43
|
+
* Uses naming convention: {entityType}-{entityId}-queue
|
|
44
|
+
*/
|
|
45
|
+
getOrCreateEntityQueue(entityType: string, entityId: string): Queue;
|
|
46
|
+
/**
|
|
47
|
+
* Close and remove a specific queue.
|
|
48
|
+
* This will gracefully close the queue and clean up resources.
|
|
49
|
+
*/
|
|
50
|
+
closeQueue(queueName: string): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Close all managed queues.
|
|
53
|
+
* Called automatically on module destroy.
|
|
54
|
+
*/
|
|
55
|
+
closeAllQueues(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Get all managed queue names.
|
|
58
|
+
*/
|
|
59
|
+
getQueueNames(): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Get all queues for a specific entity type.
|
|
62
|
+
*/
|
|
63
|
+
getEntityTypeQueues(entityType: string): IManagedQueue[];
|
|
64
|
+
/**
|
|
65
|
+
* Delete a specific job from a queue.
|
|
66
|
+
*/
|
|
67
|
+
deleteJob(queueName: string, jobId: string): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Add a job to a queue with optional configuration.
|
|
70
|
+
*/
|
|
71
|
+
addJob<T>(queueName: string, jobName: string, data: T, options?: IJobOptions): Promise<Job<T>>;
|
|
72
|
+
/**
|
|
73
|
+
* Obliterate a queue (remove all jobs and the queue itself).
|
|
74
|
+
* Use with caution - this is destructive.
|
|
75
|
+
*/
|
|
76
|
+
obliterateQueue(queueName: string): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Get jobs from a queue by state.
|
|
79
|
+
*/
|
|
80
|
+
getJobs(queueName: string, states: ('active' | 'waiting' | 'completed' | 'failed' | 'delayed')[], start?: number, end?: number): Promise<Job[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Get the job count for a queue.
|
|
83
|
+
*/
|
|
84
|
+
getJobCounts(queueName: string): Promise<{
|
|
85
|
+
waiting: number;
|
|
86
|
+
active: number;
|
|
87
|
+
completed: number;
|
|
88
|
+
failed: number;
|
|
89
|
+
delayed: number;
|
|
90
|
+
}>;
|
|
91
|
+
/**
|
|
92
|
+
* Pause a queue.
|
|
93
|
+
*/
|
|
94
|
+
pauseQueue(queueName: string): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Resume a paused queue.
|
|
97
|
+
*/
|
|
98
|
+
resumeQueue(queueName: string): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Check if a queue exists.
|
|
101
|
+
*/
|
|
102
|
+
hasQueue(queueName: string): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Get managed queue info.
|
|
105
|
+
*/
|
|
106
|
+
getManagedQueue(queueName: string): IManagedQueue | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Create a new BullMQ Queue instance with configuration.
|
|
109
|
+
*/
|
|
110
|
+
private createQueue;
|
|
111
|
+
/**
|
|
112
|
+
* Generate queue name for an entity.
|
|
113
|
+
*/
|
|
114
|
+
private getEntityQueueName;
|
|
115
|
+
/**
|
|
116
|
+
* Normalize queue name to ensure consistency.
|
|
117
|
+
*/
|
|
118
|
+
private normalizeQueueName;
|
|
119
|
+
/**
|
|
120
|
+
* Merge job options with defaults.
|
|
121
|
+
*/
|
|
122
|
+
private mergeJobOptions;
|
|
123
|
+
/**
|
|
124
|
+
* Cleanup on module destroy.
|
|
125
|
+
*/
|
|
126
|
+
onModuleDestroy(): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=queue-manager.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue-manager.service.d.ts","sourceRoot":"","sources":["../../../src/services/queue-manager/queue-manager.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,MAAM,SAAS,CAAC;AAC5B,OAAO,EACL,aAAa,EACb,aAAa,EACb,WAAW,EAEZ,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBACa,mBAAoB,YAAW,aAAa,EAAE,eAAe;IAMzC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAGa,KAAK,EAAE,KAAK,EACX,MAAM,EAAE,yBAAyB;IAKlF;;;OAGG;IACH,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK;IAuB1C;;;OAGG;IACH,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,KAAK;IAuBnE;;;OAGG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBlD;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrC;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;OAEG;IACH,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,EAAE;IAMxD;;OAEG;IACG,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhE;;OAEG;IACG,MAAM,CAAC,CAAC,EACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,CAAC,EACP,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAgBlB;;;OAGG;IACG,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBvD;;OAEG;IACG,OAAO,CACX,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,CAAC,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC,EAAE,EACrE,KAAK,SAAI,EACT,GAAG,SAAM,GACR,OAAO,CAAC,GAAG,EAAE,CAAC;IAKjB;;OAEG;IACG,YAAY,CAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IAiBF;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlD;;OAEG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMnD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC;;OAEG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAQ7D;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;OAEG;IACH,OAAO,CAAC,eAAe;IAcvB;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
|