pp-command-bus 1.5.0 → 2.0.1

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 (205) hide show
  1. package/README.md +400 -1219
  2. package/dist/command-bus/command-bus.spec.js +138 -359
  3. package/dist/command-bus/command-bus.spec.js.map +1 -1
  4. package/dist/command-bus/command.d.ts +3 -4
  5. package/dist/command-bus/command.js +3 -32
  6. package/dist/command-bus/command.js.map +1 -1
  7. package/dist/command-bus/config/command-bus-config.d.ts +80 -21
  8. package/dist/command-bus/config/command-bus-config.js +104 -58
  9. package/dist/command-bus/config/command-bus-config.js.map +1 -1
  10. package/dist/command-bus/config/command-bus-config.spec.js +174 -100
  11. package/dist/command-bus/config/command-bus-config.spec.js.map +1 -1
  12. package/dist/command-bus/index.d.ts +41 -50
  13. package/dist/command-bus/index.js +143 -127
  14. package/dist/command-bus/index.js.map +1 -1
  15. package/dist/command-bus/interceptors/index.d.ts +5 -0
  16. package/dist/command-bus/interceptors/index.js +22 -0
  17. package/dist/command-bus/interceptors/index.js.map +1 -0
  18. package/dist/command-bus/interceptors/interceptor.interface.d.ts +35 -0
  19. package/dist/command-bus/interceptors/interceptor.interface.js +3 -0
  20. package/dist/command-bus/interceptors/interceptor.interface.js.map +1 -0
  21. package/dist/command-bus/interceptors/performance-interceptor.d.ts +24 -0
  22. package/dist/command-bus/interceptors/performance-interceptor.js +86 -0
  23. package/dist/command-bus/interceptors/performance-interceptor.js.map +1 -0
  24. package/dist/command-bus/interceptors/performance-interceptor.spec.js +124 -0
  25. package/dist/command-bus/interceptors/performance-interceptor.spec.js.map +1 -0
  26. package/dist/command-bus/logging/command-logger.d.ts +2 -0
  27. package/dist/command-bus/logging/command-logger.js +7 -0
  28. package/dist/command-bus/logging/command-logger.js.map +1 -1
  29. package/dist/command-bus/logging/command-logger.spec.js +36 -0
  30. package/dist/command-bus/logging/command-logger.spec.js.map +1 -1
  31. package/dist/command-bus/serialization/index.d.ts +6 -0
  32. package/dist/command-bus/serialization/index.js +9 -0
  33. package/dist/command-bus/serialization/index.js.map +1 -0
  34. package/dist/command-bus/serialization/msgpack-serializer.d.ts +26 -0
  35. package/dist/command-bus/serialization/msgpack-serializer.js +70 -0
  36. package/dist/command-bus/serialization/msgpack-serializer.js.map +1 -0
  37. package/dist/command-bus/serialization/msgpack-serializer.spec.js +223 -0
  38. package/dist/command-bus/serialization/msgpack-serializer.spec.js.map +1 -0
  39. package/dist/command-bus/serialization/serializer.interface.d.ts +21 -0
  40. package/dist/command-bus/serialization/serializer.interface.js +3 -0
  41. package/dist/command-bus/serialization/serializer.interface.js.map +1 -0
  42. package/dist/command-bus/transport/consumer-loop.d.ts +45 -0
  43. package/dist/command-bus/transport/consumer-loop.js +90 -0
  44. package/dist/command-bus/transport/consumer-loop.js.map +1 -0
  45. package/dist/command-bus/transport/consumer-loop.spec.js +216 -0
  46. package/dist/command-bus/transport/consumer-loop.spec.js.map +1 -0
  47. package/dist/command-bus/transport/index.d.ts +21 -0
  48. package/dist/command-bus/transport/index.js +23 -0
  49. package/dist/command-bus/transport/index.js.map +1 -0
  50. package/dist/command-bus/transport/message-processor.d.ts +70 -0
  51. package/dist/command-bus/transport/message-processor.js +158 -0
  52. package/dist/command-bus/transport/message-processor.js.map +1 -0
  53. package/dist/command-bus/transport/message-processor.spec.js +185 -0
  54. package/dist/command-bus/transport/message-processor.spec.js.map +1 -0
  55. package/dist/command-bus/transport/pending-recovery.d.ts +54 -0
  56. package/dist/command-bus/transport/pending-recovery.js +139 -0
  57. package/dist/command-bus/transport/pending-recovery.js.map +1 -0
  58. package/dist/command-bus/transport/pending-recovery.spec.js +176 -0
  59. package/dist/command-bus/transport/pending-recovery.spec.js.map +1 -0
  60. package/dist/command-bus/transport/redis-codec.d.ts +24 -0
  61. package/dist/command-bus/transport/redis-codec.js +33 -0
  62. package/dist/command-bus/transport/redis-codec.js.map +1 -0
  63. package/dist/command-bus/transport/redis-codec.spec.js +53 -0
  64. package/dist/command-bus/transport/redis-codec.spec.js.map +1 -0
  65. package/dist/command-bus/transport/redis-streams-transport.d.ts +94 -0
  66. package/dist/command-bus/transport/redis-streams-transport.js +143 -0
  67. package/dist/command-bus/transport/redis-streams-transport.js.map +1 -0
  68. package/dist/command-bus/transport/redis-streams-transport.spec.js +420 -0
  69. package/dist/command-bus/transport/redis-streams-transport.spec.js.map +1 -0
  70. package/dist/command-bus/transport/rpc-handler.d.ts +39 -0
  71. package/dist/command-bus/transport/rpc-handler.js +87 -0
  72. package/dist/command-bus/transport/rpc-handler.js.map +1 -0
  73. package/dist/command-bus/transport/rpc-handler.spec.js +157 -0
  74. package/dist/command-bus/transport/rpc-handler.spec.js.map +1 -0
  75. package/dist/command-bus/transport/stream-consumer.d.ts +91 -0
  76. package/dist/command-bus/transport/stream-consumer.js +182 -0
  77. package/dist/command-bus/transport/stream-consumer.js.map +1 -0
  78. package/dist/command-bus/transport/stream-consumer.spec.js +284 -0
  79. package/dist/command-bus/transport/stream-consumer.spec.js.map +1 -0
  80. package/dist/command-bus/transport/stream-producer.d.ts +23 -0
  81. package/dist/command-bus/transport/stream-producer.js +70 -0
  82. package/dist/command-bus/transport/stream-producer.js.map +1 -0
  83. package/dist/command-bus/transport/stream-producer.spec.js +125 -0
  84. package/dist/command-bus/transport/stream-producer.spec.js.map +1 -0
  85. package/dist/command-bus/transport/transport.interface.d.ts +87 -0
  86. package/dist/command-bus/transport/transport.interface.js +3 -0
  87. package/dist/command-bus/transport/transport.interface.js.map +1 -0
  88. package/dist/command-bus/types/index.d.ts +0 -84
  89. package/dist/examples/rpc.demo.js +1 -1
  90. package/dist/examples/rpc.demo.js.map +1 -1
  91. package/dist/index.d.ts +8 -5
  92. package/dist/index.js +6 -4
  93. package/dist/index.js.map +1 -1
  94. package/dist/pp-command-bus-2.0.1.tgz +0 -0
  95. package/dist/shared/redis/connection-pool.d.ts +54 -0
  96. package/dist/shared/redis/connection-pool.js +123 -0
  97. package/dist/shared/redis/connection-pool.js.map +1 -0
  98. package/dist/shared/redis/connection-pool.spec.d.ts +1 -0
  99. package/dist/shared/redis/connection-pool.spec.js +114 -0
  100. package/dist/shared/redis/connection-pool.spec.js.map +1 -0
  101. package/dist/shared/redis/index.d.ts +5 -3
  102. package/dist/shared/redis/index.js +6 -4
  103. package/dist/shared/redis/index.js.map +1 -1
  104. package/dist/shared/redis/rpc-connection-pool.d.ts +61 -0
  105. package/dist/shared/redis/rpc-connection-pool.js +154 -0
  106. package/dist/shared/redis/rpc-connection-pool.js.map +1 -0
  107. package/dist/shared/redis/rpc-connection-pool.spec.d.ts +1 -0
  108. package/dist/shared/redis/rpc-connection-pool.spec.js +173 -0
  109. package/dist/shared/redis/rpc-connection-pool.spec.js.map +1 -0
  110. package/dist/shared/types.d.ts +0 -4
  111. package/dist/shared/utils/error-utils.d.ts +8 -0
  112. package/dist/shared/utils/error-utils.js +14 -0
  113. package/dist/shared/utils/error-utils.js.map +1 -0
  114. package/package.json +12 -12
  115. package/dist/command-bus/config/auto-config-optimizer.d.ts +0 -35
  116. package/dist/command-bus/config/auto-config-optimizer.js +0 -52
  117. package/dist/command-bus/config/auto-config-optimizer.js.map +0 -1
  118. package/dist/command-bus/config/auto-config-optimizer.spec.js +0 -42
  119. package/dist/command-bus/config/auto-config-optimizer.spec.js.map +0 -1
  120. package/dist/command-bus/job/index.d.ts +0 -6
  121. package/dist/command-bus/job/index.js +0 -15
  122. package/dist/command-bus/job/index.js.map +0 -1
  123. package/dist/command-bus/job/job-options-builder.d.ts +0 -21
  124. package/dist/command-bus/job/job-options-builder.js +0 -58
  125. package/dist/command-bus/job/job-options-builder.js.map +0 -1
  126. package/dist/command-bus/job/job-options-builder.spec.js +0 -156
  127. package/dist/command-bus/job/job-options-builder.spec.js.map +0 -1
  128. package/dist/command-bus/job/job-processor.d.ts +0 -39
  129. package/dist/command-bus/job/job-processor.js +0 -203
  130. package/dist/command-bus/job/job-processor.js.map +0 -1
  131. package/dist/command-bus/job/job-processor.spec.js +0 -436
  132. package/dist/command-bus/job/job-processor.spec.js.map +0 -1
  133. package/dist/command-bus/queue/index.d.ts +0 -5
  134. package/dist/command-bus/queue/index.js +0 -13
  135. package/dist/command-bus/queue/index.js.map +0 -1
  136. package/dist/command-bus/queue/queue-manager.d.ts +0 -56
  137. package/dist/command-bus/queue/queue-manager.js +0 -163
  138. package/dist/command-bus/queue/queue-manager.js.map +0 -1
  139. package/dist/command-bus/queue/queue-manager.spec.js +0 -371
  140. package/dist/command-bus/queue/queue-manager.spec.js.map +0 -1
  141. package/dist/command-bus/rpc/index.d.ts +0 -11
  142. package/dist/command-bus/rpc/index.js +0 -19
  143. package/dist/command-bus/rpc/index.js.map +0 -1
  144. package/dist/command-bus/rpc/payload-compression.service.d.ts +0 -50
  145. package/dist/command-bus/rpc/payload-compression.service.js +0 -215
  146. package/dist/command-bus/rpc/payload-compression.service.js.map +0 -1
  147. package/dist/command-bus/rpc/payload-compression.service.spec.js +0 -376
  148. package/dist/command-bus/rpc/payload-compression.service.spec.js.map +0 -1
  149. package/dist/command-bus/rpc/rpc-coordinator.d.ts +0 -96
  150. package/dist/command-bus/rpc/rpc-coordinator.js +0 -500
  151. package/dist/command-bus/rpc/rpc-coordinator.js.map +0 -1
  152. package/dist/command-bus/rpc/rpc-coordinator.spec.js +0 -621
  153. package/dist/command-bus/rpc/rpc-coordinator.spec.js.map +0 -1
  154. package/dist/command-bus/rpc/rpc-job-cancellation.service.d.ts +0 -82
  155. package/dist/command-bus/rpc/rpc-job-cancellation.service.js +0 -180
  156. package/dist/command-bus/rpc/rpc-job-cancellation.service.js.map +0 -1
  157. package/dist/command-bus/rpc/rpc-job-cancellation.service.spec.js +0 -286
  158. package/dist/command-bus/rpc/rpc-job-cancellation.service.spec.js.map +0 -1
  159. package/dist/command-bus/worker/index.d.ts +0 -10
  160. package/dist/command-bus/worker/index.js +0 -19
  161. package/dist/command-bus/worker/index.js.map +0 -1
  162. package/dist/command-bus/worker/worker-benchmark.d.ts +0 -71
  163. package/dist/command-bus/worker/worker-benchmark.js +0 -202
  164. package/dist/command-bus/worker/worker-benchmark.js.map +0 -1
  165. package/dist/command-bus/worker/worker-benchmark.spec.js +0 -310
  166. package/dist/command-bus/worker/worker-benchmark.spec.js.map +0 -1
  167. package/dist/command-bus/worker/worker-metrics-collector.d.ts +0 -98
  168. package/dist/command-bus/worker/worker-metrics-collector.js +0 -242
  169. package/dist/command-bus/worker/worker-metrics-collector.js.map +0 -1
  170. package/dist/command-bus/worker/worker-orchestrator.d.ts +0 -70
  171. package/dist/command-bus/worker/worker-orchestrator.js +0 -339
  172. package/dist/command-bus/worker/worker-orchestrator.js.map +0 -1
  173. package/dist/command-bus/worker/worker-orchestrator.spec.js +0 -712
  174. package/dist/command-bus/worker/worker-orchestrator.spec.js.map +0 -1
  175. package/dist/examples/auto-config.demo.d.ts +0 -9
  176. package/dist/examples/auto-config.demo.js +0 -106
  177. package/dist/examples/auto-config.demo.js.map +0 -1
  178. package/dist/examples/rpc-compression.demo.d.ts +0 -5
  179. package/dist/examples/rpc-compression.demo.js +0 -358
  180. package/dist/examples/rpc-compression.demo.js.map +0 -1
  181. package/dist/examples/rpc-resilience.demo.d.ts +0 -15
  182. package/dist/examples/rpc-resilience.demo.js +0 -233
  183. package/dist/examples/rpc-resilience.demo.js.map +0 -1
  184. package/dist/pp-command-bus-1.5.0.tgz +0 -0
  185. package/dist/shared/config/base-config.d.ts +0 -54
  186. package/dist/shared/config/base-config.js +0 -114
  187. package/dist/shared/config/base-config.js.map +0 -1
  188. package/dist/shared/config/base-config.spec.js +0 -204
  189. package/dist/shared/config/base-config.spec.js.map +0 -1
  190. package/dist/shared/config/index.d.ts +0 -1
  191. package/dist/shared/config/index.js +0 -9
  192. package/dist/shared/config/index.js.map +0 -1
  193. package/dist/shared/redis/redis-connection-factory.d.ts +0 -66
  194. package/dist/shared/redis/redis-connection-factory.js +0 -113
  195. package/dist/shared/redis/redis-connection-factory.js.map +0 -1
  196. /package/dist/command-bus/{config/auto-config-optimizer.spec.d.ts → interceptors/performance-interceptor.spec.d.ts} +0 -0
  197. /package/dist/command-bus/{job/job-options-builder.spec.d.ts → serialization/msgpack-serializer.spec.d.ts} +0 -0
  198. /package/dist/command-bus/{job/job-processor.spec.d.ts → transport/consumer-loop.spec.d.ts} +0 -0
  199. /package/dist/command-bus/{queue/queue-manager.spec.d.ts → transport/message-processor.spec.d.ts} +0 -0
  200. /package/dist/command-bus/{rpc/payload-compression.service.spec.d.ts → transport/pending-recovery.spec.d.ts} +0 -0
  201. /package/dist/command-bus/{rpc/rpc-coordinator.spec.d.ts → transport/redis-codec.spec.d.ts} +0 -0
  202. /package/dist/command-bus/{rpc/rpc-job-cancellation.service.spec.d.ts → transport/redis-streams-transport.spec.d.ts} +0 -0
  203. /package/dist/command-bus/{worker/worker-benchmark.spec.d.ts → transport/rpc-handler.spec.d.ts} +0 -0
  204. /package/dist/command-bus/{worker/worker-orchestrator.spec.d.ts → transport/stream-consumer.spec.d.ts} +0 -0
  205. /package/dist/{shared/config/base-config.spec.d.ts → command-bus/transport/stream-producer.spec.d.ts} +0 -0
@@ -1,712 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- const bullmq_1 = require("bullmq");
16
- const worker_orchestrator_1 = __importDefault(require("./worker-orchestrator"));
17
- // Mock BullMQ
18
- jest.mock('bullmq');
19
- // Mock WorkerBenchmark
20
- jest.mock('./worker-benchmark', () => {
21
- return jest.fn().mockImplementation(() => ({
22
- run: jest.fn().mockResolvedValue({
23
- recommendedConcurrency: 5,
24
- jobsPerSecond: 100,
25
- avgProcessingTime: 10,
26
- }),
27
- }));
28
- });
29
- // Mock WorkerMetricsCollector (event-driven)
30
- jest.mock('./worker-metrics-collector', () => {
31
- return jest.fn().mockImplementation(() => ({
32
- onJobActive: jest.fn(),
33
- onJobCompleted: jest.fn(),
34
- onJobFailed: jest.fn(),
35
- }));
36
- });
37
- describe('WorkerOrchestrator', () => {
38
- let workerOrchestrator;
39
- let mockRedisConnection;
40
- let mockJobProcessor;
41
- let mockLogger;
42
- let mockWorker;
43
- const concurrency = 5;
44
- const maxAttempts = 1;
45
- // Storage dla concurrency każdego workera
46
- const workerConcurrencyStorage = new Map();
47
- beforeEach(() => {
48
- jest.clearAllMocks();
49
- workerConcurrencyStorage.clear();
50
- mockLogger = {
51
- log: jest.fn(),
52
- error: jest.fn(),
53
- warn: jest.fn(),
54
- debug: jest.fn(),
55
- };
56
- // Mock Redis connection - przekazywany przez DI
57
- mockRedisConnection = {};
58
- mockJobProcessor = {
59
- process: jest.fn().mockResolvedValue({ success: true }),
60
- };
61
- // Mock Worker factory z concurrency property per-instance
62
- bullmq_1.Worker.mockImplementation((_queueName, _processor, options) => {
63
- var _a;
64
- const workerInstance = {
65
- close: jest.fn().mockResolvedValue(undefined),
66
- on: jest.fn().mockReturnThis(),
67
- removeAllListeners: jest.fn().mockReturnThis(),
68
- get concurrency() {
69
- var _a;
70
- return (_a = workerConcurrencyStorage.get(workerInstance)) !== null && _a !== void 0 ? _a : 5;
71
- },
72
- set concurrency(value) {
73
- workerConcurrencyStorage.set(workerInstance, value);
74
- },
75
- };
76
- // Ustaw początkową wartość z opcji lub domyślnie 5
77
- const initialConcurrency = (_a = options === null || options === void 0 ? void 0 : options.concurrency) !== null && _a !== void 0 ? _a : 5;
78
- workerConcurrencyStorage.set(workerInstance, initialConcurrency);
79
- mockWorker = workerInstance;
80
- return workerInstance;
81
- });
82
- workerOrchestrator = new worker_orchestrator_1.default(mockRedisConnection, mockJobProcessor, concurrency, maxAttempts, mockLogger);
83
- });
84
- describe('registerWorker', () => {
85
- it('powinno utworzyć nowy worker dla komendy', () => __awaiter(void 0, void 0, void 0, function* () {
86
- // Given
87
- const commandName = 'TestCommand';
88
- // When
89
- yield workerOrchestrator.registerWorker(commandName);
90
- // Then
91
- expect(bullmq_1.Worker).toHaveBeenCalledWith(`{${commandName}}`, expect.any(Function), expect.objectContaining({
92
- connection: mockRedisConnection,
93
- concurrency: 5, // Z benchmark result
94
- }));
95
- expect(mockLogger.log).toHaveBeenCalledWith('Benchmark zakończony - tworzę workera', expect.objectContaining({
96
- commandName,
97
- oldConcurrency: concurrency,
98
- newConcurrency: 5,
99
- }));
100
- }));
101
- it('powinno rzucić błąd gdy worker już istnieje dla komendy', () => __awaiter(void 0, void 0, void 0, function* () {
102
- // Given
103
- const commandName = 'TestCommand';
104
- yield workerOrchestrator.registerWorker(commandName);
105
- // When & Then
106
- expect(() => workerOrchestrator.registerWorker(commandName)).toThrow(`Worker dla komendy ${commandName} już istnieje`);
107
- }));
108
- it('powinno skonfigurować event handlery dla workera', () => __awaiter(void 0, void 0, void 0, function* () {
109
- // Given
110
- const commandName = 'TestCommand';
111
- // When
112
- yield workerOrchestrator.registerWorker(commandName);
113
- // Then
114
- expect(mockWorker.on).toHaveBeenCalledWith('failed', expect.any(Function));
115
- expect(mockWorker.on).toHaveBeenCalledWith('completed', expect.any(Function));
116
- expect(mockWorker.on).toHaveBeenCalledWith('active', expect.any(Function));
117
- expect(mockWorker.on).toHaveBeenCalledWith('stalled', expect.any(Function));
118
- expect(mockWorker.on).toHaveBeenCalledWith('progress', expect.any(Function));
119
- expect(mockWorker.on).toHaveBeenCalledWith('error', expect.any(Function));
120
- }));
121
- it("powinno wywołać jobProcessor.process w handler'ze workera", () => __awaiter(void 0, void 0, void 0, function* () {
122
- // Given
123
- const commandName = 'TestCommand';
124
- yield workerOrchestrator.registerWorker(commandName);
125
- const workerCalls = bullmq_1.Worker.mock.calls;
126
- const jobHandler = workerCalls[0][1];
127
- const mockJob = {
128
- id: 'job-123',
129
- data: { __id: 'cmd-123' },
130
- };
131
- // When
132
- yield jobHandler(mockJob);
133
- // Then
134
- expect(mockJobProcessor.process).toHaveBeenCalledWith(mockJob, commandName);
135
- }));
136
- it('powinno propagować błędy z jobProcessor dla BullMQ retry', () => __awaiter(void 0, void 0, void 0, function* () {
137
- // Given
138
- const commandName = 'TestCommand';
139
- const processorError = new Error('Processor error');
140
- mockJobProcessor.process.mockRejectedValueOnce(processorError);
141
- yield workerOrchestrator.registerWorker(commandName);
142
- const workerCalls = bullmq_1.Worker.mock.calls;
143
- const jobHandler = workerCalls[0][1];
144
- const mockJob = {
145
- id: 'job-123',
146
- data: { __id: 'cmd-123' },
147
- };
148
- // When & Then
149
- yield expect(jobHandler(mockJob)).rejects.toThrow('Processor error');
150
- expect(mockLogger.error).toHaveBeenCalledWith('Worker handler critical error', expect.objectContaining({
151
- commandName,
152
- jobId: 'job-123',
153
- error: 'Processor error',
154
- }));
155
- }));
156
- });
157
- describe('setupWorkerEventHandlers', () => {
158
- it("powinno zalogować event 'failed'", () => __awaiter(void 0, void 0, void 0, function* () {
159
- // Given
160
- const commandName = 'TestCommand';
161
- yield workerOrchestrator.registerWorker(commandName);
162
- const failedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'failed')[1];
163
- const mockJob = {
164
- id: 'job-123',
165
- data: { __id: 'cmd-123' },
166
- attemptsMade: 0,
167
- opts: { attempts: maxAttempts },
168
- };
169
- const error = new Error('Job failed');
170
- // When
171
- failedHandler(mockJob, error);
172
- // Then
173
- expect(mockLogger.error).toHaveBeenCalledWith('Job zakończony niepowodzeniem', expect.objectContaining({
174
- commandName,
175
- jobId: 'job-123',
176
- error: 'Job failed',
177
- attempt: 0,
178
- maxAttempts,
179
- isRetryable: true,
180
- }));
181
- }));
182
- it("powinno zalogować event 'completed'", () => __awaiter(void 0, void 0, void 0, function* () {
183
- // Given
184
- const commandName = 'TestCommand';
185
- yield workerOrchestrator.registerWorker(commandName);
186
- const completedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'completed')[1];
187
- const mockJob = {
188
- id: 'job-123',
189
- data: { __id: 'cmd-123' },
190
- returnvalue: { success: true },
191
- };
192
- // When
193
- completedHandler(mockJob);
194
- // Then
195
- expect(mockLogger.log).toHaveBeenCalledWith('Job zakończony pomyślnie', expect.objectContaining({
196
- commandName,
197
- jobId: 'job-123',
198
- hasReturnValue: true,
199
- }));
200
- }));
201
- it("powinno zalogować event 'active'", () => __awaiter(void 0, void 0, void 0, function* () {
202
- // Given
203
- const commandName = 'TestCommand';
204
- yield workerOrchestrator.registerWorker(commandName);
205
- const activeHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'active')[1];
206
- const mockJob = {
207
- id: 'job-123',
208
- data: { __id: 'cmd-123' },
209
- };
210
- // When
211
- activeHandler(mockJob);
212
- // Then
213
- expect(mockLogger.debug).toHaveBeenCalledWith('Job rozpoczęty', expect.objectContaining({
214
- commandName,
215
- jobId: 'job-123',
216
- }));
217
- }));
218
- it("powinno zalogować event 'stalled'", () => __awaiter(void 0, void 0, void 0, function* () {
219
- // Given
220
- const commandName = 'TestCommand';
221
- yield workerOrchestrator.registerWorker(commandName);
222
- const stalledHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'stalled')[1];
223
- const jobId = 'job-123';
224
- // When
225
- stalledHandler(jobId);
226
- // Then
227
- expect(mockLogger.warn).toHaveBeenCalledWith('Job zatrzymany (stalled)', expect.objectContaining({
228
- commandName,
229
- jobId,
230
- reason: 'Prawdopodobnie worker przestał odpowiadać',
231
- }));
232
- }));
233
- it("powinno zalogować event 'progress'", () => __awaiter(void 0, void 0, void 0, function* () {
234
- // Given
235
- const commandName = 'TestCommand';
236
- yield workerOrchestrator.registerWorker(commandName);
237
- const progressHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'progress')[1];
238
- const mockJob = {
239
- id: 'job-123',
240
- data: { __id: 'cmd-123' },
241
- };
242
- const progress = 50;
243
- // When
244
- progressHandler(mockJob, progress);
245
- // Then
246
- expect(mockLogger.debug).toHaveBeenCalledWith('Job - postęp przetwarzania', expect.objectContaining({
247
- commandName,
248
- jobId: 'job-123',
249
- progress: 50,
250
- }));
251
- }));
252
- it("powinno zalogować event 'error'", () => __awaiter(void 0, void 0, void 0, function* () {
253
- // Given
254
- const commandName = 'TestCommand';
255
- yield workerOrchestrator.registerWorker(commandName);
256
- const errorHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'error')[1];
257
- const error = new Error('Worker error');
258
- // When
259
- errorHandler(error);
260
- // Then
261
- expect(mockLogger.error).toHaveBeenCalledWith('Błąd workera', expect.objectContaining({
262
- commandName,
263
- error: 'Worker error',
264
- }));
265
- }));
266
- it('powinno obsłużyć brak attempt info w failed event', () => __awaiter(void 0, void 0, void 0, function* () {
267
- // Given
268
- const commandName = 'TestCommand';
269
- yield workerOrchestrator.registerWorker(commandName);
270
- const failedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'failed')[1];
271
- const mockJob = {
272
- id: 'job-123',
273
- data: { __id: 'cmd-123' },
274
- // Brak attemptsMade i opts
275
- };
276
- const error = new Error('Job failed');
277
- // When
278
- failedHandler(mockJob, error);
279
- // Then
280
- expect(mockLogger.error).toHaveBeenCalledWith('Job zakończony niepowodzeniem', expect.objectContaining({
281
- attempt: undefined, // attemptsMade jest undefined gdy nie ma tej właściwości
282
- maxAttempts,
283
- isRetryable: true, // (0 || 0) < maxAttempts = true
284
- }));
285
- }));
286
- });
287
- describe('getWorker', () => {
288
- it('powinno zwrócić workera dla komendy', () => __awaiter(void 0, void 0, void 0, function* () {
289
- // Given
290
- const commandName = 'TestCommand';
291
- yield workerOrchestrator.registerWorker(commandName);
292
- // When
293
- const worker = workerOrchestrator.getWorker(commandName);
294
- // Then
295
- expect(worker).toBe(mockWorker);
296
- }));
297
- it('powinno zwrócić undefined dla niezarejestrowanego workera', () => {
298
- // When
299
- const worker = workerOrchestrator.getWorker('NonExistentCommand');
300
- // Then
301
- expect(worker).toBeUndefined();
302
- });
303
- });
304
- describe('closeAll', () => {
305
- it('powinno zamknąć wszystkich workerów', () => __awaiter(void 0, void 0, void 0, function* () {
306
- // Given
307
- yield workerOrchestrator.registerWorker('TestCommand1');
308
- yield workerOrchestrator.registerWorker('TestCommand2');
309
- yield workerOrchestrator.registerWorker('TestCommand3');
310
- const worker1 = workerOrchestrator.getWorker('TestCommand1');
311
- const worker2 = workerOrchestrator.getWorker('TestCommand2');
312
- const worker3 = workerOrchestrator.getWorker('TestCommand3');
313
- // When
314
- yield workerOrchestrator.closeAll();
315
- // Then - każdy worker powinien mieć wywołane close
316
- expect(worker1 === null || worker1 === void 0 ? void 0 : worker1.close).toHaveBeenCalledTimes(1);
317
- expect(worker2 === null || worker2 === void 0 ? void 0 : worker2.close).toHaveBeenCalledTimes(1);
318
- expect(worker3 === null || worker3 === void 0 ? void 0 : worker3.close).toHaveBeenCalledTimes(1);
319
- }));
320
- it('powinno wyczyścić cache workerów', () => __awaiter(void 0, void 0, void 0, function* () {
321
- // Given
322
- yield workerOrchestrator.registerWorker('TestCommand');
323
- yield workerOrchestrator.closeAll();
324
- // When
325
- const worker = workerOrchestrator.getWorker('TestCommand');
326
- // Then
327
- expect(worker).toBeUndefined();
328
- }));
329
- it('powinno działać gdy brak workerów', () => __awaiter(void 0, void 0, void 0, function* () {
330
- // When & Then
331
- yield expect(workerOrchestrator.closeAll()).resolves.toBeUndefined();
332
- }));
333
- it('powinno wyczyścić wszystkie collectory metryk', () => __awaiter(void 0, void 0, void 0, function* () {
334
- // Given
335
- yield workerOrchestrator.registerWorker('TestCommand');
336
- // When
337
- yield workerOrchestrator.closeAll();
338
- // Then - event-driven collectors nie wymagają stop(), tylko cleanup referencji
339
- const stats = workerOrchestrator.getWorkerStats();
340
- expect(stats.activeWorkersCount).toBe(0);
341
- }));
342
- it('powinno usunąć wszystkie event listeners przed zamknięciem', () => __awaiter(void 0, void 0, void 0, function* () {
343
- // Given
344
- yield workerOrchestrator.registerWorker('TestCommand');
345
- // When
346
- yield workerOrchestrator.closeAll();
347
- // Then
348
- expect(mockWorker.removeAllListeners).toHaveBeenCalled();
349
- }));
350
- });
351
- describe('adjustConcurrency', () => {
352
- beforeEach(() => {
353
- jest.useFakeTimers();
354
- });
355
- afterEach(() => {
356
- // Wyczyść wszystkie pending timery przed przywróceniem real timers
357
- jest.clearAllTimers();
358
- jest.useRealTimers();
359
- });
360
- it('powinno zwiększyć concurrency o 20%', () => __awaiter(void 0, void 0, void 0, function* () {
361
- // Given - użyj wyższego początkowego concurrency żeby test był sensowny
362
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
363
- WorkerBenchmark.mockImplementation(() => ({
364
- run: jest.fn().mockResolvedValue({
365
- recommendedConcurrency: 50, // Wysokie początkowe concurrency
366
- jobsPerSecond: 100,
367
- avgProcessingTime: 10,
368
- }),
369
- }));
370
- const commandName = 'TestCommand';
371
- yield workerOrchestrator.registerWorker(commandName);
372
- const worker = workerOrchestrator.getWorker(commandName);
373
- // When
374
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'Test reason');
375
- // Then: 50 * 1.2 = 60
376
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(60);
377
- expect(mockLogger.log).toHaveBeenCalledWith('Dynamiczna zmiana concurrency', expect.objectContaining({
378
- commandName,
379
- oldConcurrency: 50,
380
- newConcurrency: 60,
381
- change: '+20%',
382
- direction: 'increase',
383
- reason: 'Test reason',
384
- }));
385
- }));
386
- it('powinno zmniejszyć concurrency o 20%', () => __awaiter(void 0, void 0, void 0, function* () {
387
- // Given - użyj wyższego początkowego concurrency
388
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
389
- WorkerBenchmark.mockImplementation(() => ({
390
- run: jest.fn().mockResolvedValue({
391
- recommendedConcurrency: 50,
392
- jobsPerSecond: 100,
393
- avgProcessingTime: 10,
394
- }),
395
- }));
396
- const commandName = 'TestCommand';
397
- yield workerOrchestrator.registerWorker(commandName);
398
- const worker = workerOrchestrator.getWorker(commandName);
399
- // When
400
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'Low backlog');
401
- // Then: 50 * 0.8 = 40
402
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(40);
403
- expect(mockLogger.log).toHaveBeenCalledWith('Dynamiczna zmiana concurrency', expect.objectContaining({
404
- oldConcurrency: 50,
405
- newConcurrency: 40,
406
- change: '-20%',
407
- direction: 'decrease',
408
- }));
409
- }));
410
- it('powinno zastosować limit minimum 10', () => __awaiter(void 0, void 0, void 0, function* () {
411
- // Given
412
- const commandName = 'TestCommand';
413
- yield workerOrchestrator.registerWorker(commandName);
414
- const worker = workerOrchestrator.getWorker(commandName);
415
- // Zmniejsz kilka razy do limitu
416
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
417
- jest.advanceTimersByTime(31000); // Przekrocz cooldown
418
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
419
- jest.advanceTimersByTime(31000);
420
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
421
- jest.advanceTimersByTime(31000);
422
- // When - próba zmniejszenia poniżej 10
423
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
424
- // Then - powinno zatrzymać się na 10
425
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBeGreaterThanOrEqual(10);
426
- }));
427
- it('powinno zastosować limit maksimum 2000', () => __awaiter(void 0, void 0, void 0, function* () {
428
- // Given - mockuj benchmark aby zwrócił wysokie concurrency
429
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
430
- WorkerBenchmark.mockImplementation(() => ({
431
- run: jest.fn().mockResolvedValue({
432
- recommendedConcurrency: 1800,
433
- jobsPerSecond: 1000,
434
- avgProcessingTime: 5,
435
- }),
436
- }));
437
- const commandName = 'HighConcurrencyCommand';
438
- yield workerOrchestrator.registerWorker(commandName);
439
- const worker = workerOrchestrator.getWorker(commandName);
440
- // Zwiększ kilka razy
441
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason');
442
- jest.advanceTimersByTime(31000);
443
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason');
444
- jest.advanceTimersByTime(31000);
445
- // When - próba zwiększenia powyżej 2000
446
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason');
447
- // Then - powinno zatrzymać się na 2000
448
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBeLessThanOrEqual(2000);
449
- }));
450
- it('powinno respektować cooldown 30s między zmianami', () => __awaiter(void 0, void 0, void 0, function* () {
451
- // Given
452
- const commandName = 'TestCommand';
453
- yield workerOrchestrator.registerWorker(commandName);
454
- const worker = workerOrchestrator.getWorker(commandName);
455
- // First change
456
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason 1');
457
- const firstConcurrency = worker === null || worker === void 0 ? void 0 : worker.concurrency;
458
- // When - próba zmiany w czasie cooldown
459
- jest.advanceTimersByTime(15000); // 15s - poniżej cooldown
460
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason 2');
461
- // Then - concurrency nie powinno się zmienić
462
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(firstConcurrency);
463
- expect(mockLogger.debug).toHaveBeenCalledWith('Cooldown aktywny - pomijam zmianę concurrency', expect.any(Object));
464
- }));
465
- it('powinno pozwolić na zmianę po upływie cooldown', () => __awaiter(void 0, void 0, void 0, function* () {
466
- var _a;
467
- // Given - użyj wyższego początkowego concurrency
468
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
469
- WorkerBenchmark.mockImplementation(() => ({
470
- run: jest.fn().mockResolvedValue({
471
- recommendedConcurrency: 1000,
472
- jobsPerSecond: 100,
473
- avgProcessingTime: 10,
474
- }),
475
- }));
476
- const commandName = 'TestCommand';
477
- yield workerOrchestrator.registerWorker(commandName);
478
- const worker = workerOrchestrator.getWorker(commandName);
479
- // First change: 1000 * 1.2 = 1200
480
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason 1');
481
- const firstConcurrency = (_a = worker === null || worker === void 0 ? void 0 : worker.concurrency) !== null && _a !== void 0 ? _a : 0;
482
- expect(firstConcurrency).toBe(1200);
483
- // When - czekamy > 30s i zmieniamy ponownie
484
- jest.advanceTimersByTime(31000); // 31s - powyżej cooldown
485
- workerOrchestrator.adjustConcurrency(commandName, 'increase', 'reason 2');
486
- // Then - concurrency powinno się zmienić: 1200 * 1.2 = 1440
487
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(1440);
488
- }));
489
- it('powinno zalogować warning gdy worker nie istnieje', () => {
490
- // When
491
- workerOrchestrator.adjustConcurrency('NonExistentCommand', 'increase', 'reason');
492
- // Then
493
- expect(mockLogger.warn).toHaveBeenCalledWith('Nie można dostosować concurrency - worker nie istnieje', expect.objectContaining({
494
- commandName: 'NonExistentCommand',
495
- }));
496
- });
497
- it('nie powinno zmieniać concurrency gdy wartość się nie zmienia (na limicie)', () => __awaiter(void 0, void 0, void 0, function* () {
498
- var _a;
499
- // Given - zresetuj mock benchmark do domyślnych wartości
500
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
501
- WorkerBenchmark.mockImplementation(() => ({
502
- run: jest.fn().mockResolvedValue({
503
- recommendedConcurrency: 50, // Wystarczająco wysokie aby test miał sens
504
- jobsPerSecond: 100,
505
- avgProcessingTime: 10,
506
- }),
507
- }));
508
- const commandName = 'TestCommand';
509
- yield workerOrchestrator.registerWorker(commandName);
510
- const worker = workerOrchestrator.getWorker(commandName);
511
- // Ustaw na minimum (10): 50 -> 40 -> 32 -> 26 -> 21 -> 17 -> 14 -> 11 -> 10 -> 10
512
- for (let i = 0; i < 10; i++) {
513
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
514
- jest.advanceTimersByTime(31000);
515
- }
516
- const minConcurrency = (_a = worker === null || worker === void 0 ? void 0 : worker.concurrency) !== null && _a !== void 0 ? _a : 0;
517
- expect(minConcurrency).toBe(10); // Powinno osiągnąć minimum 10
518
- // When - próba dalszego zmniejszenia na limicie
519
- workerOrchestrator.adjustConcurrency(commandName, 'decrease', 'reason');
520
- // Then - wartość nie powinna się zmienić
521
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(minConcurrency);
522
- expect(mockLogger.debug).toHaveBeenCalledWith('Concurrency bez zmian - osiągnięto limit', expect.any(Object));
523
- }));
524
- });
525
- describe('integracja z WorkerBenchmark', () => {
526
- it('powinno uruchomić benchmark przed utworzeniem workera', () => __awaiter(void 0, void 0, void 0, function* () {
527
- // Given
528
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
529
- const commandName = 'TestCommand';
530
- // When
531
- yield workerOrchestrator.registerWorker(commandName);
532
- // Then
533
- expect(WorkerBenchmark).toHaveBeenCalledWith(commandName, mockRedisConnection, mockJobProcessor, mockLogger);
534
- const benchmarkInstance = WorkerBenchmark.mock.results[0].value;
535
- expect(benchmarkInstance.run).toHaveBeenCalled();
536
- }));
537
- it('powinno użyć recommendedConcurrency z benchmarku', () => __awaiter(void 0, void 0, void 0, function* () {
538
- // Given
539
- const WorkerBenchmark = jest.requireMock('./worker-benchmark');
540
- WorkerBenchmark.mockImplementation(() => ({
541
- run: jest.fn().mockResolvedValue({
542
- recommendedConcurrency: 42,
543
- jobsPerSecond: 200,
544
- avgProcessingTime: 20,
545
- }),
546
- }));
547
- const commandName = 'OptimizedCommand';
548
- // When
549
- yield workerOrchestrator.registerWorker(commandName);
550
- // Poczekaj na zakończenie asynchronicznego benchmarku
551
- yield new Promise((resolve) => setTimeout(resolve, 100));
552
- // Then - sprawdź że concurrency zostało zaktualizowane po benchmarku
553
- const worker = workerOrchestrator.getWorker(commandName);
554
- expect(worker === null || worker === void 0 ? void 0 : worker.concurrency).toBe(42);
555
- }), 15000);
556
- });
557
- describe('integracja z WorkerMetricsCollector', () => {
558
- it('powinno utworzyć metrics collector (event-driven)', () => __awaiter(void 0, void 0, void 0, function* () {
559
- // Given
560
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
561
- const commandName = 'TestCommand';
562
- // When
563
- yield workerOrchestrator.registerWorker(commandName);
564
- // Then
565
- expect(WorkerMetricsCollector).toHaveBeenCalledWith(commandName, mockLogger, expect.any(Function));
566
- // Event-driven collector nie wymaga start() - działa od razu
567
- const collectorInstance = WorkerMetricsCollector.mock.results[0].value;
568
- expect(collectorInstance.onJobActive).toBeDefined();
569
- expect(collectorInstance.onJobCompleted).toBeDefined();
570
- expect(collectorInstance.onJobFailed).toBeDefined();
571
- }));
572
- it('powinno wywołać adjustConcurrency gdy collector rekomenduje zmianę', () => __awaiter(void 0, void 0, void 0, function* () {
573
- // Given
574
- const commandName = 'TestCommand';
575
- yield workerOrchestrator.registerWorker(commandName);
576
- // Pobierz callback przekazany do WorkerMetricsCollector (pozycja 2: commandName, logger, callback)
577
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
578
- const collectorCallback = WorkerMetricsCollector.mock.calls[0][2];
579
- // When - symuluj rekomendację od collectora
580
- collectorCallback({
581
- shouldAdjust: true,
582
- direction: 'increase',
583
- reason: 'High backlog detected',
584
- currentMetrics: {
585
- waiting: 100,
586
- active: 10,
587
- jobsPerSecond: 5,
588
- avgProcessingTimeMs: 200,
589
- timestamp: Date.now(),
590
- },
591
- });
592
- // Then
593
- expect(mockWorker.concurrency).toBeGreaterThan(5); // Zwiększone o 20%
594
- }));
595
- it('nie powinno wywoływać adjustConcurrency gdy direction=none', () => __awaiter(void 0, void 0, void 0, function* () {
596
- // Given
597
- const commandName = 'TestCommand';
598
- yield workerOrchestrator.registerWorker(commandName);
599
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
600
- const collectorCallback = WorkerMetricsCollector.mock.calls[0][2];
601
- const initialConcurrency = mockWorker.concurrency;
602
- // When - symuluj brak rekomendacji
603
- collectorCallback({
604
- shouldAdjust: false,
605
- direction: 'none',
606
- reason: 'Stable metrics',
607
- currentMetrics: {
608
- waiting: 10,
609
- active: 10,
610
- jobsPerSecond: 10,
611
- avgProcessingTimeMs: 100,
612
- timestamp: Date.now(),
613
- },
614
- });
615
- // Then - concurrency nie zmienione
616
- expect(mockWorker.concurrency).toBe(initialConcurrency);
617
- }));
618
- });
619
- describe('tracking czasu przetwarzania jobów', () => {
620
- beforeEach(() => {
621
- jest.useFakeTimers();
622
- });
623
- afterEach(() => {
624
- // Wyczyść wszystkie pending timery przed przywróceniem real timers
625
- jest.clearAllTimers();
626
- jest.useRealTimers();
627
- });
628
- it('powinno zapisać czas przetwarzania w metricsCollector', () => __awaiter(void 0, void 0, void 0, function* () {
629
- // Given
630
- const commandName = 'TestCommand';
631
- yield workerOrchestrator.registerWorker(commandName);
632
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
633
- const collectorInstance = WorkerMetricsCollector.mock.results[0].value;
634
- // Pobierz handlery eventów
635
- const activeHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'active')[1];
636
- const completedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'completed')[1];
637
- const mockJob = {
638
- id: 'job-123',
639
- data: { __id: 'cmd-123' },
640
- returnvalue: { success: true },
641
- };
642
- // When - symuluj job lifecycle
643
- activeHandler(mockJob); // Start job
644
- jest.advanceTimersByTime(150); // 150ms przetwarzania
645
- completedHandler(mockJob); // Complete job
646
- // Then - event-driven metrics: onJobActive i onJobCompleted
647
- expect(collectorInstance.onJobActive).toHaveBeenCalledWith('job-123');
648
- expect(collectorInstance.onJobCompleted).toHaveBeenCalledWith('job-123', 150);
649
- }));
650
- it('powinno obsłużyć sytuację gdy brak jobId', () => __awaiter(void 0, void 0, void 0, function* () {
651
- // Given
652
- const commandName = 'TestCommand';
653
- yield workerOrchestrator.registerWorker(commandName);
654
- const completedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'completed')[1];
655
- const mockJob = {
656
- id: undefined, // Brak ID
657
- data: { __id: 'cmd-123' },
658
- };
659
- // When
660
- completedHandler(mockJob);
661
- // Then - nie powinno wywołać onJobCompleted
662
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
663
- const collectorInstance = WorkerMetricsCollector.mock.results[0].value;
664
- expect(collectorInstance.onJobCompleted).not.toHaveBeenCalled();
665
- }));
666
- it('powinno wywołać onJobFailed dla failed jobs', () => __awaiter(void 0, void 0, void 0, function* () {
667
- // Given
668
- const commandName = 'TestCommand';
669
- yield workerOrchestrator.registerWorker(commandName);
670
- const activeHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'active')[1];
671
- const failedHandler = mockWorker.on.mock.calls.find((call) => call[0] === 'failed')[1];
672
- const mockJob = {
673
- id: 'job-123',
674
- data: { __id: 'cmd-123' },
675
- attemptsMade: 1,
676
- opts: { attempts: 1 },
677
- };
678
- const WorkerMetricsCollector = jest.requireMock('./worker-metrics-collector');
679
- const collectorInstance = WorkerMetricsCollector.mock.results[0].value;
680
- // When - job fails
681
- activeHandler(mockJob);
682
- failedHandler(mockJob, new Error('Job failed'));
683
- // Then - event-driven metrics: onJobActive i onJobFailed
684
- expect(collectorInstance.onJobActive).toHaveBeenCalledWith('job-123');
685
- expect(collectorInstance.onJobFailed).toHaveBeenCalledWith('job-123');
686
- }));
687
- });
688
- describe('getWorkerStats', () => {
689
- it('powinno zwrócić statystyki workerów', () => __awaiter(void 0, void 0, void 0, function* () {
690
- // Given
691
- yield workerOrchestrator.registerWorker('Command1');
692
- yield workerOrchestrator.registerWorker('Command2');
693
- // When
694
- const stats = workerOrchestrator.getWorkerStats();
695
- // Then
696
- expect(stats).toEqual({
697
- activeWorkersCount: 2,
698
- workerNames: ['Command1', 'Command2'],
699
- });
700
- }));
701
- it('powinno zwrócić puste statystyki gdy brak workerów', () => {
702
- // When
703
- const stats = workerOrchestrator.getWorkerStats();
704
- // Then
705
- expect(stats).toEqual({
706
- activeWorkersCount: 0,
707
- workerNames: [],
708
- });
709
- });
710
- });
711
- });
712
- //# sourceMappingURL=worker-orchestrator.spec.js.map