pp-command-bus 1.0.2 → 1.1.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/dist/command-bus/command-bus.spec.js +26 -8
- package/dist/command-bus/command-bus.spec.js.map +1 -1
- package/dist/command-bus/config/auto-config-optimizer.d.ts +35 -0
- package/dist/command-bus/config/auto-config-optimizer.js +52 -0
- package/dist/command-bus/config/auto-config-optimizer.js.map +1 -0
- package/dist/command-bus/config/auto-config-optimizer.spec.d.ts +1 -0
- package/dist/command-bus/config/auto-config-optimizer.spec.js +42 -0
- package/dist/command-bus/config/auto-config-optimizer.spec.js.map +1 -0
- package/dist/command-bus/config/command-bus-config.d.ts +6 -0
- package/dist/command-bus/config/command-bus-config.js +33 -6
- package/dist/command-bus/config/command-bus-config.js.map +1 -1
- package/dist/command-bus/config/command-bus-config.spec.js +62 -2
- package/dist/command-bus/config/command-bus-config.spec.js.map +1 -1
- package/dist/command-bus/index.d.ts +4 -0
- package/dist/command-bus/index.js +21 -6
- package/dist/command-bus/index.js.map +1 -1
- package/dist/command-bus/job/job-processor.d.ts +2 -0
- package/dist/command-bus/job/job-processor.js +50 -2
- package/dist/command-bus/job/job-processor.js.map +1 -1
- package/dist/command-bus/job/job-processor.spec.js +13 -0
- package/dist/command-bus/job/job-processor.spec.js.map +1 -1
- package/dist/command-bus/queue/queue-manager.d.ts +35 -3
- package/dist/command-bus/queue/queue-manager.js +107 -4
- package/dist/command-bus/queue/queue-manager.js.map +1 -1
- package/dist/command-bus/queue/queue-manager.spec.js +155 -3
- package/dist/command-bus/queue/queue-manager.spec.js.map +1 -1
- package/dist/command-bus/rpc/rpc-coordinator.js +6 -1
- package/dist/command-bus/rpc/rpc-coordinator.js.map +1 -1
- package/dist/command-bus/rpc/rpc-coordinator.spec.js +211 -0
- package/dist/command-bus/rpc/rpc-coordinator.spec.js.map +1 -1
- package/dist/command-bus/worker/index.d.ts +6 -1
- package/dist/command-bus/worker/index.js +8 -2
- package/dist/command-bus/worker/index.js.map +1 -1
- package/dist/command-bus/worker/worker-benchmark.d.ts +70 -0
- package/dist/command-bus/worker/worker-benchmark.js +210 -0
- package/dist/command-bus/worker/worker-benchmark.js.map +1 -0
- package/dist/command-bus/worker/worker-benchmark.spec.d.ts +1 -0
- package/dist/command-bus/worker/worker-benchmark.spec.js +300 -0
- package/dist/command-bus/worker/worker-benchmark.spec.js.map +1 -0
- package/dist/command-bus/worker/worker-metrics-collector.d.ts +87 -0
- package/dist/command-bus/worker/worker-metrics-collector.js +259 -0
- package/dist/command-bus/worker/worker-metrics-collector.js.map +1 -0
- package/dist/command-bus/worker/worker-metrics-collector.spec.d.ts +1 -0
- package/dist/command-bus/worker/worker-metrics-collector.spec.js +315 -0
- package/dist/command-bus/worker/worker-metrics-collector.spec.js.map +1 -0
- package/dist/command-bus/worker/worker-orchestrator.d.ts +29 -4
- package/dist/command-bus/worker/worker-orchestrator.js +198 -27
- package/dist/command-bus/worker/worker-orchestrator.js.map +1 -1
- package/dist/command-bus/worker/worker-orchestrator.spec.js +473 -52
- package/dist/command-bus/worker/worker-orchestrator.spec.js.map +1 -1
- package/dist/examples/auto-config.demo.d.ts +9 -0
- package/dist/examples/auto-config.demo.js +106 -0
- package/dist/examples/auto-config.demo.js.map +1 -0
- package/dist/examples/rpc-throughput.demo.d.ts +5 -0
- package/dist/examples/rpc-throughput.demo.js +326 -0
- package/dist/examples/rpc-throughput.demo.js.map +1 -0
- package/dist/pp-command-bus-1.1.0.tgz +0 -0
- package/package.json +3 -2
- package/dist/pp-command-bus-1.0.2.tgz +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
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 auto_config_optimizer_1 = __importDefault(require("../config/auto-config-optimizer"));
|
|
16
|
+
const command_1 = __importDefault(require("../command"));
|
|
17
|
+
const crypto_1 = require("crypto");
|
|
18
|
+
/**
|
|
19
|
+
* Testowa komenda dla benchmarku
|
|
20
|
+
*/
|
|
21
|
+
class BenchmarkTestCommand extends command_1.default {
|
|
22
|
+
constructor(testId) {
|
|
23
|
+
super();
|
|
24
|
+
this.testId = testId;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Szybki benchmark workera (~1-2s)
|
|
29
|
+
* Mierzy latencję Redis, przepustowość workera i czas przetwarzania handlera
|
|
30
|
+
*/
|
|
31
|
+
class WorkerBenchmark {
|
|
32
|
+
constructor(commandName, redisConnection, jobProcessor, logger) {
|
|
33
|
+
this.commandName = commandName;
|
|
34
|
+
this.redisConnection = redisConnection;
|
|
35
|
+
this.jobProcessor = jobProcessor;
|
|
36
|
+
this.logger = logger;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Uruchamia benchmark i zwraca wyniki z rekomendowanym concurrency
|
|
40
|
+
*/
|
|
41
|
+
run() {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
this.logger.log(`Rozpoczynam benchmark dla ${this.commandName}`, {
|
|
44
|
+
commandName: this.commandName,
|
|
45
|
+
timestamp: new Date().toISOString(),
|
|
46
|
+
});
|
|
47
|
+
const startTime = Date.now();
|
|
48
|
+
// Zbierz metryki
|
|
49
|
+
const redisLatencyMs = yield this.measureRedisLatency();
|
|
50
|
+
const handlerAvgTimeMs = yield this.measureHandlerTime();
|
|
51
|
+
const systemInfo = auto_config_optimizer_1.default.getSystemInfo();
|
|
52
|
+
// Oblicz rekomendowane concurrency
|
|
53
|
+
const recommendedConcurrency = this.calculateConcurrency(redisLatencyMs, handlerAvgTimeMs, systemInfo);
|
|
54
|
+
const totalTime = Date.now() - startTime;
|
|
55
|
+
const result = {
|
|
56
|
+
redisLatencyMs,
|
|
57
|
+
workerThroughputJobsPerSec: 0, // Pominiemy throughput test dla prostoty
|
|
58
|
+
handlerAvgTimeMs,
|
|
59
|
+
systemInfo,
|
|
60
|
+
recommendedConcurrency,
|
|
61
|
+
};
|
|
62
|
+
this.logger.log('Benchmark zakończony', Object.assign(Object.assign({ commandName: this.commandName }, result), { benchmarkDurationMs: totalTime, timestamp: new Date().toISOString() }));
|
|
63
|
+
return result;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Mierzy latencję Redis (ping + set/get)
|
|
68
|
+
* @returns Średnia latencja w ms
|
|
69
|
+
*/
|
|
70
|
+
measureRedisLatency() {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const measurements = [];
|
|
73
|
+
try {
|
|
74
|
+
// 10 prób ping
|
|
75
|
+
for (let i = 0; i < 10; i++) {
|
|
76
|
+
const start = Date.now();
|
|
77
|
+
yield this.redisConnection.ping();
|
|
78
|
+
measurements.push(Date.now() - start);
|
|
79
|
+
}
|
|
80
|
+
// 10 prób set/get
|
|
81
|
+
for (let i = 0; i < 10; i++) {
|
|
82
|
+
const key = `{benchmark:${this.commandName}:${i}:${(0, crypto_1.randomUUID)()}}`;
|
|
83
|
+
const value = `test-value-${i}`;
|
|
84
|
+
const setStart = Date.now();
|
|
85
|
+
yield this.redisConnection.set(key, value);
|
|
86
|
+
measurements.push(Date.now() - setStart);
|
|
87
|
+
const getStart = Date.now();
|
|
88
|
+
yield this.redisConnection.get(key);
|
|
89
|
+
measurements.push(Date.now() - getStart);
|
|
90
|
+
yield this.redisConnection.del(key);
|
|
91
|
+
}
|
|
92
|
+
return this.calculateAverage(measurements);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.logger.error('Błąd podczas pomiaru latencji Redis', {
|
|
96
|
+
commandName: this.commandName,
|
|
97
|
+
error: error instanceof Error ? error.message : String(error),
|
|
98
|
+
});
|
|
99
|
+
// Fallback: zakładamy średnią latencję
|
|
100
|
+
return 5;
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Mierzy średni czas przetwarzania handlera
|
|
106
|
+
* Symuluje losowy delay 50-10000ms dla realistycznego benchmarku
|
|
107
|
+
* @returns Średni czas w ms
|
|
108
|
+
*/
|
|
109
|
+
measureHandlerTime() {
|
|
110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
111
|
+
const measurements = [];
|
|
112
|
+
try {
|
|
113
|
+
// 100 wywołań testowych
|
|
114
|
+
for (let i = 0; i < 100; i++) {
|
|
115
|
+
const testCommand = new BenchmarkTestCommand(i);
|
|
116
|
+
const mockJob = {
|
|
117
|
+
id: `{benchmark-job-${i}:${(0, crypto_1.randomUUID)()}}`,
|
|
118
|
+
data: testCommand,
|
|
119
|
+
opts: {},
|
|
120
|
+
attemptsMade: 0,
|
|
121
|
+
};
|
|
122
|
+
const start = Date.now();
|
|
123
|
+
try {
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
yield this.jobProcessor.process(mockJob, this.commandName);
|
|
126
|
+
}
|
|
127
|
+
catch (_a) {
|
|
128
|
+
// Ignoruj błędy handlera w benchmarku
|
|
129
|
+
}
|
|
130
|
+
const duration = Date.now() - start;
|
|
131
|
+
// Symuluj losowy delay handlera (50-5000ms)
|
|
132
|
+
const randomDelay = this.getRandomDelay(50, 5000);
|
|
133
|
+
const totalDuration = duration + randomDelay;
|
|
134
|
+
if (totalDuration > 0) {
|
|
135
|
+
measurements.push(totalDuration);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Jeśli nie udało się zmierzyć, zwróć fallback
|
|
139
|
+
if (measurements.length === 0) {
|
|
140
|
+
return 50;
|
|
141
|
+
}
|
|
142
|
+
return this.calculateAverage(measurements);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.logger.error('Błąd podczas pomiaru czasu handlera', {
|
|
146
|
+
commandName: this.commandName,
|
|
147
|
+
error: error instanceof Error ? error.message : String(error),
|
|
148
|
+
});
|
|
149
|
+
// Fallback: zakładamy średni czas
|
|
150
|
+
return 50;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Oblicza rekomendowane concurrency na podstawie metryk
|
|
156
|
+
*/
|
|
157
|
+
calculateConcurrency(redisLatencyMs, handlerAvgTimeMs, systemInfo) {
|
|
158
|
+
const { cpuCount, freeMemoryGB } = systemInfo;
|
|
159
|
+
// Bazowy concurrency dla I/O-heavy workload
|
|
160
|
+
let baseConcurrency = cpuCount * 50;
|
|
161
|
+
// Korekta dla dostępnej pamięci RAM
|
|
162
|
+
if (freeMemoryGB < 2) {
|
|
163
|
+
baseConcurrency *= 0.3;
|
|
164
|
+
}
|
|
165
|
+
else if (freeMemoryGB < 4) {
|
|
166
|
+
baseConcurrency *= 0.5;
|
|
167
|
+
}
|
|
168
|
+
else if (freeMemoryGB >= 16) {
|
|
169
|
+
baseConcurrency *= 1.2;
|
|
170
|
+
}
|
|
171
|
+
let factor = 1.0;
|
|
172
|
+
// Korekta dla latencji Redis - bardziej agresywna
|
|
173
|
+
if (redisLatencyMs < 1) {
|
|
174
|
+
factor *= 1.5; // Bardzo szybki Redis
|
|
175
|
+
}
|
|
176
|
+
else if (redisLatencyMs > 10) {
|
|
177
|
+
factor *= 0.3; // Wolny Redis - mocniejsza redukcja
|
|
178
|
+
}
|
|
179
|
+
// Korekta dla czasu handlera - bardziej agresywna
|
|
180
|
+
if (handlerAvgTimeMs < 10) {
|
|
181
|
+
factor *= 1.2; // Szybki handler
|
|
182
|
+
}
|
|
183
|
+
else if (handlerAvgTimeMs > 100) {
|
|
184
|
+
factor *= 0.5; // Wolny handler - mocniejsza redukcja
|
|
185
|
+
}
|
|
186
|
+
const recommendedConcurrency = Math.round(baseConcurrency * factor);
|
|
187
|
+
// Zapewnij sensowne granice: min 10, max 2000
|
|
188
|
+
return Math.max(10, Math.min(2000, recommendedConcurrency));
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Oblicza średnią z tablicy wartości
|
|
192
|
+
*/
|
|
193
|
+
calculateAverage(values) {
|
|
194
|
+
if (values.length === 0)
|
|
195
|
+
return 0;
|
|
196
|
+
const sum = values.reduce((acc, val) => acc + val, 0);
|
|
197
|
+
return Number((sum / values.length).toFixed(2));
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Generuje losowy delay w zadanym zakresie
|
|
201
|
+
* @param min - Minimalna wartość w ms
|
|
202
|
+
* @param max - Maksymalna wartość w ms
|
|
203
|
+
* @returns Losowy delay w ms
|
|
204
|
+
*/
|
|
205
|
+
getRandomDelay(min, max) {
|
|
206
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = WorkerBenchmark;
|
|
210
|
+
//# sourceMappingURL=worker-benchmark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-benchmark.js","sourceRoot":"","sources":["../../../src/command-bus/worker/worker-benchmark.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,300 @@
|
|
|
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 __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
const worker_benchmark_1 = __importDefault(require("./worker-benchmark"));
|
|
49
|
+
const os = __importStar(require("os"));
|
|
50
|
+
// Mock os module
|
|
51
|
+
jest.mock('os');
|
|
52
|
+
describe('WorkerBenchmark', () => {
|
|
53
|
+
let mockRedis;
|
|
54
|
+
let mockJobProcessor;
|
|
55
|
+
let mockLogger;
|
|
56
|
+
let benchmark;
|
|
57
|
+
beforeEach(() => {
|
|
58
|
+
// Mock Redis
|
|
59
|
+
mockRedis = {
|
|
60
|
+
ping: jest.fn().mockResolvedValue('PONG'),
|
|
61
|
+
set: jest.fn().mockResolvedValue('OK'),
|
|
62
|
+
get: jest.fn().mockResolvedValue('test-value'),
|
|
63
|
+
del: jest.fn().mockResolvedValue(1),
|
|
64
|
+
};
|
|
65
|
+
// Mock JobProcessor
|
|
66
|
+
mockJobProcessor = {
|
|
67
|
+
process: jest.fn().mockResolvedValue({ success: true }),
|
|
68
|
+
};
|
|
69
|
+
// Mock Logger
|
|
70
|
+
mockLogger = {
|
|
71
|
+
log: jest.fn(),
|
|
72
|
+
debug: jest.fn(),
|
|
73
|
+
error: jest.fn(),
|
|
74
|
+
warn: jest.fn(),
|
|
75
|
+
};
|
|
76
|
+
// Mock os functions (używamy availableParallelism zamiast cpus)
|
|
77
|
+
os.availableParallelism.mockReturnValue(8); // 8 cores
|
|
78
|
+
os.freemem.mockReturnValue(8 * 1024 * 1024 * 1024); // 8GB free
|
|
79
|
+
os.totalmem.mockReturnValue(16 * 1024 * 1024 * 1024); // 16GB total
|
|
80
|
+
});
|
|
81
|
+
describe('run', () => {
|
|
82
|
+
it('powinien uruchomić pełny benchmark i zwrócić wyniki', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
83
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
84
|
+
const result = yield benchmark.run();
|
|
85
|
+
expect(result).toEqual(expect.objectContaining({
|
|
86
|
+
redisLatencyMs: expect.any(Number),
|
|
87
|
+
workerThroughputJobsPerSec: 0, // Pomijamy throughput test
|
|
88
|
+
handlerAvgTimeMs: expect.any(Number),
|
|
89
|
+
systemInfo: expect.objectContaining({
|
|
90
|
+
cpuCount: 8,
|
|
91
|
+
freeMemoryGB: expect.any(Number),
|
|
92
|
+
totalMemoryGB: expect.any(Number),
|
|
93
|
+
}),
|
|
94
|
+
recommendedConcurrency: expect.any(Number),
|
|
95
|
+
}));
|
|
96
|
+
expect(mockLogger.log).toHaveBeenCalledWith('Rozpoczynam benchmark dla TestCommand', expect.any(Object));
|
|
97
|
+
expect(mockLogger.log).toHaveBeenCalledWith('Benchmark zakończony', expect.any(Object));
|
|
98
|
+
}));
|
|
99
|
+
it('powinien zalogować czas trwania benchmarku', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
100
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
101
|
+
yield benchmark.run();
|
|
102
|
+
expect(mockLogger.log).toHaveBeenCalledWith('Benchmark zakończony', expect.objectContaining({
|
|
103
|
+
benchmarkDurationMs: expect.any(Number),
|
|
104
|
+
}));
|
|
105
|
+
}));
|
|
106
|
+
});
|
|
107
|
+
describe('measureRedisLatency', () => {
|
|
108
|
+
it('powinien zmierzyć latencję Redis (ping + set/get)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
109
|
+
// Symuluj opóźnienia Redis
|
|
110
|
+
mockRedis.ping.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 2)));
|
|
111
|
+
mockRedis.set.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 3)));
|
|
112
|
+
mockRedis.get.mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 1)));
|
|
113
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
114
|
+
const result = yield benchmark.run();
|
|
115
|
+
// Sprawdź że latencja została zmierzona
|
|
116
|
+
expect(result.redisLatencyMs).toBeGreaterThan(0);
|
|
117
|
+
// Sprawdź że wykonano odpowiednią liczbę operacji
|
|
118
|
+
expect(mockRedis.ping).toHaveBeenCalledTimes(10); // 10 ping
|
|
119
|
+
expect(mockRedis.set).toHaveBeenCalledTimes(10); // 10 set
|
|
120
|
+
expect(mockRedis.get).toHaveBeenCalledTimes(10); // 10 get
|
|
121
|
+
expect(mockRedis.del).toHaveBeenCalledTimes(10); // 10 del (cleanup)
|
|
122
|
+
}));
|
|
123
|
+
it('powinien użyć fallback latencji gdy Redis zwraca błąd', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
124
|
+
mockRedis.ping.mockRejectedValue(new Error('Redis connection error'));
|
|
125
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
126
|
+
const result = yield benchmark.run();
|
|
127
|
+
// Fallback latencja: 5ms
|
|
128
|
+
expect(result.redisLatencyMs).toBe(5);
|
|
129
|
+
expect(mockLogger.error).toHaveBeenCalledWith('Błąd podczas pomiaru latencji Redis', expect.objectContaining({
|
|
130
|
+
commandName: 'TestCommand',
|
|
131
|
+
error: 'Redis connection error',
|
|
132
|
+
}));
|
|
133
|
+
}));
|
|
134
|
+
it('powinien używać unikalnych kluczy Redis dla każdego pomiaru', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
136
|
+
yield benchmark.run();
|
|
137
|
+
// Sprawdź że klucze są unikalne (zawierają UUID)
|
|
138
|
+
const setCalls = mockRedis.set.mock.calls;
|
|
139
|
+
const keys = setCalls.map((call) => call[0]);
|
|
140
|
+
// Wszystkie klucze powinny być różne
|
|
141
|
+
const uniqueKeys = new Set(keys);
|
|
142
|
+
expect(uniqueKeys.size).toBe(keys.length);
|
|
143
|
+
// Klucze powinny mieć format: {benchmark:TestCommand:i:uuid}
|
|
144
|
+
keys.forEach((key) => {
|
|
145
|
+
expect(key).toMatch(/^{benchmark:TestCommand:\d+:[a-f0-9-]+}$/);
|
|
146
|
+
});
|
|
147
|
+
}));
|
|
148
|
+
});
|
|
149
|
+
describe('measureHandlerTime', () => {
|
|
150
|
+
it('powinien zmierzyć średni czas przetwarzania handlera', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
152
|
+
const result = yield benchmark.run();
|
|
153
|
+
// Sprawdź że czas handlera został zmierzony
|
|
154
|
+
expect(result.handlerAvgTimeMs).toBeGreaterThan(0);
|
|
155
|
+
// Sprawdź że wykonano 100 wywołań
|
|
156
|
+
expect(mockJobProcessor.process).toHaveBeenCalledTimes(100);
|
|
157
|
+
}));
|
|
158
|
+
it('powinien symulować losowy delay handlera (50-5000ms)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
159
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
160
|
+
const result = yield benchmark.run();
|
|
161
|
+
// Czas powinien być w zakresie min 50ms (bez błędów handlera)
|
|
162
|
+
expect(result.handlerAvgTimeMs).toBeGreaterThanOrEqual(50);
|
|
163
|
+
}));
|
|
164
|
+
it('powinien ignorować błędy handlera w benchmarku', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
165
|
+
mockJobProcessor.process.mockRejectedValue(new Error('Handler error'));
|
|
166
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
167
|
+
const result = yield benchmark.run();
|
|
168
|
+
// Benchmark powinien zakończyć się pomyślnie mimo błędów handlera
|
|
169
|
+
expect(result.handlerAvgTimeMs).toBeGreaterThanOrEqual(0);
|
|
170
|
+
}));
|
|
171
|
+
it('powinien użyć fallback czasu gdy brak pomiarów', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
172
|
+
// Symuluj scenariusz gdzie wszystkie pomiary są nieprawidłowe
|
|
173
|
+
mockJobProcessor.process.mockImplementation(() => {
|
|
174
|
+
throw new Error('Critical error');
|
|
175
|
+
});
|
|
176
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
177
|
+
const result = yield benchmark.run();
|
|
178
|
+
// Fallback: 50ms
|
|
179
|
+
expect(result.handlerAvgTimeMs).toBeGreaterThanOrEqual(50);
|
|
180
|
+
}));
|
|
181
|
+
});
|
|
182
|
+
describe('calculateConcurrency', () => {
|
|
183
|
+
it('powinien obliczyć bazowy concurrency (cpuCount * 50)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
184
|
+
// 8 cores * 50 = 400
|
|
185
|
+
os.availableParallelism.mockReturnValue(8);
|
|
186
|
+
os.freemem.mockReturnValue(8 * 1024 * 1024 * 1024); // 8GB
|
|
187
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
188
|
+
const result = yield benchmark.run();
|
|
189
|
+
// Bazowy: 8 * 50 = 400
|
|
190
|
+
// Z korektami powinien być w rozsądnym zakresie
|
|
191
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
192
|
+
expect(result.recommendedConcurrency).toBeLessThanOrEqual(2000);
|
|
193
|
+
}));
|
|
194
|
+
it('powinien zastosować korektę dla niskiej RAM (< 2GB)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
195
|
+
os.availableParallelism.mockReturnValue(8);
|
|
196
|
+
os.freemem.mockReturnValue(1.5 * 1024 * 1024 * 1024); // 1.5GB
|
|
197
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
198
|
+
const result = yield benchmark.run();
|
|
199
|
+
// Bazowy: 8 * 50 = 400
|
|
200
|
+
// Korekta < 2GB: * 0.3 = 120
|
|
201
|
+
// Z innymi korektami może być jeszcze niższy lub wyższy
|
|
202
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
203
|
+
}));
|
|
204
|
+
it('powinien zastosować korektę dla średniej RAM (< 4GB)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
205
|
+
os.availableParallelism.mockReturnValue(8);
|
|
206
|
+
os.freemem.mockReturnValue(3 * 1024 * 1024 * 1024); // 3GB
|
|
207
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
208
|
+
const result = yield benchmark.run();
|
|
209
|
+
// Bazowy: 8 * 50 = 400
|
|
210
|
+
// Korekta < 4GB: * 0.5 = 200
|
|
211
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
212
|
+
}));
|
|
213
|
+
it('powinien zastosować korektę dla wysokiej RAM (>= 16GB)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
os.availableParallelism.mockReturnValue(8);
|
|
215
|
+
os.freemem.mockReturnValue(20 * 1024 * 1024 * 1024); // 20GB
|
|
216
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
217
|
+
const result = yield benchmark.run();
|
|
218
|
+
// Bazowy: 8 * 50 = 400
|
|
219
|
+
// Korekta >= 16GB: * 1.2 = 480
|
|
220
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
221
|
+
}));
|
|
222
|
+
it('powinien zwiększyć concurrency dla szybkiego Redis (< 1ms)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
223
|
+
// Symuluj bardzo szybki Redis
|
|
224
|
+
mockRedis.ping.mockImplementation(() => Promise.resolve('PONG'));
|
|
225
|
+
mockRedis.set.mockImplementation(() => Promise.resolve('OK'));
|
|
226
|
+
mockRedis.get.mockImplementation(() => Promise.resolve('value'));
|
|
227
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
228
|
+
const result = yield benchmark.run();
|
|
229
|
+
// Redis latency powinno być < 1ms, co daje factor * 1.5
|
|
230
|
+
expect(result.redisLatencyMs).toBeLessThan(1);
|
|
231
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
232
|
+
}));
|
|
233
|
+
it('powinien zmniejszyć concurrency dla wolnego Redis (> 10ms)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
234
|
+
// Symuluj wolny Redis - wszystkie operacje opóźnione
|
|
235
|
+
mockRedis.ping.mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve('PONG'), 15)));
|
|
236
|
+
mockRedis.set.mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve('OK'), 15)));
|
|
237
|
+
mockRedis.get.mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve('value'), 15)));
|
|
238
|
+
// Ustaw wystarczające zasoby żeby nie było zbyt dużej redukcji
|
|
239
|
+
os.availableParallelism.mockReturnValue(8);
|
|
240
|
+
os.freemem.mockReturnValue(8 * 1024 * 1024 * 1024); // 8GB
|
|
241
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
242
|
+
const result = yield benchmark.run();
|
|
243
|
+
// Redis latency > 10ms, co daje factor * 0.3, ale limity zapewniają min 10
|
|
244
|
+
expect(result.redisLatencyMs).toBeGreaterThan(10);
|
|
245
|
+
expect(result.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
246
|
+
}));
|
|
247
|
+
it('powinien zastosować limity: min 10, max 2000', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
248
|
+
// Przypadek 1: Bardzo niska konfiguracja
|
|
249
|
+
os.availableParallelism.mockReturnValue(1); // 1 core
|
|
250
|
+
os.freemem.mockReturnValue(0.5 * 1024 * 1024 * 1024); // 0.5GB
|
|
251
|
+
mockRedis.ping.mockImplementation(() => new Promise((resolve) => setTimeout(() => resolve('PONG'), 50)));
|
|
252
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
253
|
+
const result1 = yield benchmark.run();
|
|
254
|
+
// Minimum 10
|
|
255
|
+
expect(result1.recommendedConcurrency).toBeGreaterThanOrEqual(10);
|
|
256
|
+
// Przypadek 2: Bardzo wysoka konfiguracja
|
|
257
|
+
os.availableParallelism.mockReturnValue(64); // 64 cores
|
|
258
|
+
os.freemem.mockReturnValue(128 * 1024 * 1024 * 1024); // 128GB
|
|
259
|
+
mockRedis.ping.mockResolvedValue('PONG'); // Natychmiastowy ping
|
|
260
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
261
|
+
const result2 = yield benchmark.run();
|
|
262
|
+
// Maximum 2000
|
|
263
|
+
expect(result2.recommendedConcurrency).toBeLessThanOrEqual(2000);
|
|
264
|
+
}));
|
|
265
|
+
});
|
|
266
|
+
describe('calculateAverage', () => {
|
|
267
|
+
it('powinien obliczyć średnią z wartości', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
268
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
269
|
+
const result = yield benchmark.run();
|
|
270
|
+
// Sprawdź że średnie są zaokrąglone do 2 miejsc po przecinku
|
|
271
|
+
expect(result.redisLatencyMs).toEqual(expect.any(Number));
|
|
272
|
+
expect(result.handlerAvgTimeMs).toEqual(expect.any(Number));
|
|
273
|
+
}));
|
|
274
|
+
});
|
|
275
|
+
describe('getRandomDelay', () => {
|
|
276
|
+
it('powinien generować losowy delay w zadanym zakresie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
277
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
278
|
+
const result = yield benchmark.run();
|
|
279
|
+
// Handler time powinien zawierać losowy delay 50-5000ms
|
|
280
|
+
expect(result.handlerAvgTimeMs).toBeGreaterThanOrEqual(50);
|
|
281
|
+
}));
|
|
282
|
+
});
|
|
283
|
+
describe('integracja z systemInfo', () => {
|
|
284
|
+
it('powinien zwrócić poprawne informacje o systemie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
285
|
+
os.availableParallelism.mockReturnValue(12);
|
|
286
|
+
os.freemem.mockReturnValue(10 * 1024 * 1024 * 1024);
|
|
287
|
+
os.totalmem.mockReturnValue(32 * 1024 * 1024 * 1024);
|
|
288
|
+
benchmark = new worker_benchmark_1.default('TestCommand', mockRedis, mockJobProcessor, mockLogger);
|
|
289
|
+
const result = yield benchmark.run();
|
|
290
|
+
expect(result.systemInfo).toEqual({
|
|
291
|
+
cpuCount: 12,
|
|
292
|
+
freeMemoryGB: expect.any(Number),
|
|
293
|
+
totalMemoryGB: expect.any(Number),
|
|
294
|
+
});
|
|
295
|
+
expect(result.systemInfo.freeMemoryGB).toBeCloseTo(10, 1);
|
|
296
|
+
expect(result.systemInfo.totalMemoryGB).toBeCloseTo(32, 1);
|
|
297
|
+
}));
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
//# sourceMappingURL=worker-benchmark.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker-benchmark.spec.js","sourceRoot":"","sources":["../../../src/command-bus/worker/worker-benchmark.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import type { Queue } from 'bullmq';
|
|
2
|
+
import type { ILogger } from '../../shared/types';
|
|
3
|
+
/**
|
|
4
|
+
* Snapshot metryk dla analizy trendu
|
|
5
|
+
*/
|
|
6
|
+
interface MetricsSnapshot {
|
|
7
|
+
waiting: number;
|
|
8
|
+
active: number;
|
|
9
|
+
jobsPerSecond: number;
|
|
10
|
+
avgProcessingTimeMs: number;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Rekomendacja zmiany concurrency
|
|
15
|
+
*/
|
|
16
|
+
interface ConcurrencyRecommendation {
|
|
17
|
+
shouldAdjust: boolean;
|
|
18
|
+
direction: 'increase' | 'decrease' | 'none';
|
|
19
|
+
reason: string;
|
|
20
|
+
currentMetrics: MetricsSnapshot;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Zbiera i loguje metryki diagnostyczne workera co 5 sekund
|
|
24
|
+
*/
|
|
25
|
+
export default class WorkerMetricsCollector {
|
|
26
|
+
private readonly commandName;
|
|
27
|
+
private readonly queue;
|
|
28
|
+
private readonly logger;
|
|
29
|
+
private readonly onConcurrencyRecommendation?;
|
|
30
|
+
private intervalId?;
|
|
31
|
+
private previousCompleted;
|
|
32
|
+
private previousTimestamp;
|
|
33
|
+
private processingTimes;
|
|
34
|
+
/**
|
|
35
|
+
* Okno przesuwne dla ostatnich 10 pomiarów metryk (50s historii)
|
|
36
|
+
*/
|
|
37
|
+
private metricsHistory;
|
|
38
|
+
private readonly maxHistorySize;
|
|
39
|
+
constructor(commandName: string, queue: Queue, logger: ILogger, onConcurrencyRecommendation?: ((recommendation: ConcurrencyRecommendation) => void) | undefined);
|
|
40
|
+
/**
|
|
41
|
+
* Uruchamia zbieranie metryk co 5 sekund
|
|
42
|
+
*/
|
|
43
|
+
start(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Zatrzymuje zbieranie metryk
|
|
46
|
+
*/
|
|
47
|
+
stop(): void;
|
|
48
|
+
/**
|
|
49
|
+
* Rejestruje czas przetwarzania joba (w ms)
|
|
50
|
+
*/
|
|
51
|
+
recordJobProcessingTime(durationMs: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Zbiera metryki z kolejki i loguje
|
|
54
|
+
*/
|
|
55
|
+
private collectMetrics;
|
|
56
|
+
/**
|
|
57
|
+
* Oblicza przepustowość (jobs/sec, jobs/min) na podstawie różnicy completed
|
|
58
|
+
*/
|
|
59
|
+
private calculateThroughput;
|
|
60
|
+
/**
|
|
61
|
+
* Oblicza średni czas przetwarzania z zebranych pomiarów
|
|
62
|
+
*/
|
|
63
|
+
private calculateAvgProcessingTime;
|
|
64
|
+
/**
|
|
65
|
+
* Dodaje snapshot metryk do okna przesuwnego (max 10 pomiarów)
|
|
66
|
+
*/
|
|
67
|
+
private addToHistory;
|
|
68
|
+
/**
|
|
69
|
+
* Analizuje trendy w metrykach i rekomenduje zmianę concurrency
|
|
70
|
+
* Warunki zwiększenia (wszystkie muszą być true):
|
|
71
|
+
* - waiting > active * 2 (duży backlog)
|
|
72
|
+
* - Trend waiting: rośnie w 7/10 ostatnich pomiarów
|
|
73
|
+
* - Trend throughput: rośnie w 7/10 pomiarów
|
|
74
|
+
*
|
|
75
|
+
* Warunki zmniejszenia (wszystkie muszą być true):
|
|
76
|
+
* - waiting < active / 2 (mało pending)
|
|
77
|
+
* - Trend waiting: maleje w 7/10 ostatnich pomiarów
|
|
78
|
+
* - Trend throughput: maleje w 7/10 pomiarów
|
|
79
|
+
*/
|
|
80
|
+
private analyzeMetricsAndRecommendConcurrency;
|
|
81
|
+
/**
|
|
82
|
+
* Analizuje trend dla danej metryki
|
|
83
|
+
* @returns 'increasing' jeśli rośnie w 7/10 pomiarów, 'decreasing' jeśli maleje, 'stable' w przeciwnym razie
|
|
84
|
+
*/
|
|
85
|
+
private analyzeTrend;
|
|
86
|
+
}
|
|
87
|
+
export {};
|