pp-command-bus 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +402 -1113
- package/dist/command-bus/command-bus.spec.js +144 -370
- package/dist/command-bus/command-bus.spec.js.map +1 -1
- package/dist/command-bus/command.d.ts +23 -5
- package/dist/command-bus/command.js +20 -34
- package/dist/command-bus/command.js.map +1 -1
- package/dist/command-bus/config/command-bus-config.d.ts +75 -21
- package/dist/command-bus/config/command-bus-config.js +99 -58
- package/dist/command-bus/config/command-bus-config.js.map +1 -1
- package/dist/command-bus/config/command-bus-config.spec.js +174 -100
- package/dist/command-bus/config/command-bus-config.spec.js.map +1 -1
- package/dist/command-bus/index.d.ts +39 -52
- package/dist/command-bus/index.js +133 -126
- package/dist/command-bus/index.js.map +1 -1
- package/dist/command-bus/logging/command-logger.d.ts +2 -0
- package/dist/command-bus/logging/command-logger.js +7 -0
- package/dist/command-bus/logging/command-logger.js.map +1 -1
- package/dist/command-bus/logging/command-logger.spec.js +49 -14
- package/dist/command-bus/logging/command-logger.spec.js.map +1 -1
- package/dist/command-bus/serialization/index.d.ts +6 -0
- package/dist/command-bus/serialization/index.js +9 -0
- package/dist/command-bus/serialization/index.js.map +1 -0
- package/dist/command-bus/serialization/msgpack-serializer.d.ts +26 -0
- package/dist/command-bus/serialization/msgpack-serializer.js +70 -0
- package/dist/command-bus/serialization/msgpack-serializer.js.map +1 -0
- package/dist/command-bus/serialization/msgpack-serializer.spec.js +223 -0
- package/dist/command-bus/serialization/msgpack-serializer.spec.js.map +1 -0
- package/dist/command-bus/serialization/serializer.interface.d.ts +21 -0
- package/dist/command-bus/serialization/serializer.interface.js +3 -0
- package/dist/command-bus/serialization/serializer.interface.js.map +1 -0
- package/dist/command-bus/transport/consumer-loop.d.ts +45 -0
- package/dist/command-bus/transport/consumer-loop.js +90 -0
- package/dist/command-bus/transport/consumer-loop.js.map +1 -0
- package/dist/command-bus/transport/consumer-loop.spec.js +216 -0
- package/dist/command-bus/transport/consumer-loop.spec.js.map +1 -0
- package/dist/command-bus/transport/index.d.ts +21 -0
- package/dist/command-bus/transport/index.js +23 -0
- package/dist/command-bus/transport/index.js.map +1 -0
- package/dist/command-bus/transport/message-processor.d.ts +59 -0
- package/dist/command-bus/transport/message-processor.js +111 -0
- package/dist/command-bus/transport/message-processor.js.map +1 -0
- package/dist/command-bus/transport/message-processor.spec.js +185 -0
- package/dist/command-bus/transport/message-processor.spec.js.map +1 -0
- package/dist/command-bus/transport/pending-recovery.d.ts +54 -0
- package/dist/command-bus/transport/pending-recovery.js +139 -0
- package/dist/command-bus/transport/pending-recovery.js.map +1 -0
- package/dist/command-bus/transport/pending-recovery.spec.js +176 -0
- package/dist/command-bus/transport/pending-recovery.spec.js.map +1 -0
- package/dist/command-bus/transport/redis-codec.d.ts +24 -0
- package/dist/command-bus/transport/redis-codec.js +33 -0
- package/dist/command-bus/transport/redis-codec.js.map +1 -0
- package/dist/command-bus/transport/redis-codec.spec.js +53 -0
- package/dist/command-bus/transport/redis-codec.spec.js.map +1 -0
- package/dist/command-bus/transport/redis-streams-transport.d.ts +91 -0
- package/dist/command-bus/transport/redis-streams-transport.js +134 -0
- package/dist/command-bus/transport/redis-streams-transport.js.map +1 -0
- package/dist/command-bus/transport/redis-streams-transport.spec.js +420 -0
- package/dist/command-bus/transport/redis-streams-transport.spec.js.map +1 -0
- package/dist/command-bus/transport/rpc-handler.d.ts +39 -0
- package/dist/command-bus/transport/rpc-handler.js +87 -0
- package/dist/command-bus/transport/rpc-handler.js.map +1 -0
- package/dist/command-bus/transport/rpc-handler.spec.js +157 -0
- package/dist/command-bus/transport/rpc-handler.spec.js.map +1 -0
- package/dist/command-bus/transport/stream-consumer.d.ts +89 -0
- package/dist/command-bus/transport/stream-consumer.js +181 -0
- package/dist/command-bus/transport/stream-consumer.js.map +1 -0
- package/dist/command-bus/transport/stream-consumer.spec.js +284 -0
- package/dist/command-bus/transport/stream-consumer.spec.js.map +1 -0
- package/dist/command-bus/transport/stream-producer.d.ts +23 -0
- package/dist/command-bus/transport/stream-producer.js +70 -0
- package/dist/command-bus/transport/stream-producer.js.map +1 -0
- package/dist/command-bus/transport/stream-producer.spec.js +125 -0
- package/dist/command-bus/transport/stream-producer.spec.js.map +1 -0
- package/dist/command-bus/transport/transport.interface.d.ts +87 -0
- package/dist/command-bus/transport/transport.interface.js +3 -0
- package/dist/command-bus/transport/transport.interface.js.map +1 -0
- package/dist/command-bus/types/index.d.ts +9 -80
- package/dist/examples/rpc-throughput.demo.js +24 -22
- package/dist/examples/rpc-throughput.demo.js.map +1 -1
- package/dist/examples/rpc.demo.js +47 -53
- package/dist/examples/rpc.demo.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/pp-command-bus-2.0.0.tgz +0 -0
- package/dist/shared/redis/connection-pool.d.ts +54 -0
- package/dist/shared/redis/connection-pool.js +117 -0
- package/dist/shared/redis/connection-pool.js.map +1 -0
- package/dist/shared/redis/connection-pool.spec.js +114 -0
- package/dist/shared/redis/connection-pool.spec.js.map +1 -0
- package/dist/shared/redis/index.d.ts +5 -3
- package/dist/shared/redis/index.js +6 -4
- package/dist/shared/redis/index.js.map +1 -1
- package/dist/shared/redis/rpc-connection-pool.d.ts +61 -0
- package/dist/shared/redis/rpc-connection-pool.js +154 -0
- package/dist/shared/redis/rpc-connection-pool.js.map +1 -0
- package/dist/shared/redis/rpc-connection-pool.spec.d.ts +1 -0
- package/dist/shared/redis/rpc-connection-pool.spec.js +173 -0
- package/dist/shared/redis/rpc-connection-pool.spec.js.map +1 -0
- package/dist/shared/types.d.ts +0 -4
- package/dist/shared/utils/error-utils.d.ts +8 -0
- package/dist/shared/utils/error-utils.js +14 -0
- package/dist/shared/utils/error-utils.js.map +1 -0
- package/package.json +12 -12
- package/dist/command-bus/config/auto-config-optimizer.d.ts +0 -35
- package/dist/command-bus/config/auto-config-optimizer.js +0 -52
- package/dist/command-bus/config/auto-config-optimizer.js.map +0 -1
- package/dist/command-bus/config/auto-config-optimizer.spec.js +0 -42
- package/dist/command-bus/config/auto-config-optimizer.spec.js.map +0 -1
- package/dist/command-bus/job/index.d.ts +0 -6
- package/dist/command-bus/job/index.js +0 -15
- package/dist/command-bus/job/index.js.map +0 -1
- package/dist/command-bus/job/job-options-builder.d.ts +0 -21
- package/dist/command-bus/job/job-options-builder.js +0 -58
- package/dist/command-bus/job/job-options-builder.js.map +0 -1
- package/dist/command-bus/job/job-options-builder.spec.js +0 -156
- package/dist/command-bus/job/job-options-builder.spec.js.map +0 -1
- package/dist/command-bus/job/job-processor.d.ts +0 -39
- package/dist/command-bus/job/job-processor.js +0 -203
- package/dist/command-bus/job/job-processor.js.map +0 -1
- package/dist/command-bus/job/job-processor.spec.js +0 -437
- package/dist/command-bus/job/job-processor.spec.js.map +0 -1
- package/dist/command-bus/queue/index.d.ts +0 -5
- package/dist/command-bus/queue/index.js +0 -13
- package/dist/command-bus/queue/index.js.map +0 -1
- package/dist/command-bus/queue/queue-manager.d.ts +0 -56
- package/dist/command-bus/queue/queue-manager.js +0 -163
- package/dist/command-bus/queue/queue-manager.js.map +0 -1
- package/dist/command-bus/queue/queue-manager.spec.js +0 -371
- package/dist/command-bus/queue/queue-manager.spec.js.map +0 -1
- package/dist/command-bus/rpc/index.d.ts +0 -11
- package/dist/command-bus/rpc/index.js +0 -19
- package/dist/command-bus/rpc/index.js.map +0 -1
- package/dist/command-bus/rpc/payload-compression.service.d.ts +0 -51
- package/dist/command-bus/rpc/payload-compression.service.js +0 -218
- package/dist/command-bus/rpc/payload-compression.service.js.map +0 -1
- package/dist/command-bus/rpc/payload-compression.service.spec.js +0 -379
- package/dist/command-bus/rpc/payload-compression.service.spec.js.map +0 -1
- package/dist/command-bus/rpc/rpc-coordinator.d.ts +0 -96
- package/dist/command-bus/rpc/rpc-coordinator.js +0 -500
- package/dist/command-bus/rpc/rpc-coordinator.js.map +0 -1
- package/dist/command-bus/rpc/rpc-coordinator.spec.js +0 -622
- package/dist/command-bus/rpc/rpc-coordinator.spec.js.map +0 -1
- package/dist/command-bus/rpc/rpc-job-cancellation.service.d.ts +0 -82
- package/dist/command-bus/rpc/rpc-job-cancellation.service.js +0 -180
- package/dist/command-bus/rpc/rpc-job-cancellation.service.js.map +0 -1
- package/dist/command-bus/rpc/rpc-job-cancellation.service.spec.js +0 -286
- package/dist/command-bus/rpc/rpc-job-cancellation.service.spec.js.map +0 -1
- package/dist/command-bus/worker/index.d.ts +0 -10
- package/dist/command-bus/worker/index.js +0 -19
- package/dist/command-bus/worker/index.js.map +0 -1
- package/dist/command-bus/worker/worker-benchmark.d.ts +0 -71
- package/dist/command-bus/worker/worker-benchmark.js +0 -203
- package/dist/command-bus/worker/worker-benchmark.js.map +0 -1
- package/dist/command-bus/worker/worker-benchmark.spec.js +0 -310
- package/dist/command-bus/worker/worker-benchmark.spec.js.map +0 -1
- package/dist/command-bus/worker/worker-metrics-collector.d.ts +0 -98
- package/dist/command-bus/worker/worker-metrics-collector.js +0 -242
- package/dist/command-bus/worker/worker-metrics-collector.js.map +0 -1
- package/dist/command-bus/worker/worker-orchestrator.d.ts +0 -70
- package/dist/command-bus/worker/worker-orchestrator.js +0 -339
- package/dist/command-bus/worker/worker-orchestrator.js.map +0 -1
- package/dist/command-bus/worker/worker-orchestrator.spec.js +0 -712
- package/dist/command-bus/worker/worker-orchestrator.spec.js.map +0 -1
- package/dist/examples/auto-config.demo.d.ts +0 -9
- package/dist/examples/auto-config.demo.js +0 -106
- package/dist/examples/auto-config.demo.js.map +0 -1
- package/dist/examples/rpc-compression.demo.d.ts +0 -5
- package/dist/examples/rpc-compression.demo.js +0 -363
- package/dist/examples/rpc-compression.demo.js.map +0 -1
- package/dist/examples/rpc-resilience.demo.d.ts +0 -11
- package/dist/examples/rpc-resilience.demo.js +0 -235
- package/dist/examples/rpc-resilience.demo.js.map +0 -1
- package/dist/pp-command-bus-1.4.0.tgz +0 -0
- package/dist/shared/config/base-config.d.ts +0 -54
- package/dist/shared/config/base-config.js +0 -114
- package/dist/shared/config/base-config.js.map +0 -1
- package/dist/shared/config/base-config.spec.js +0 -204
- package/dist/shared/config/base-config.spec.js.map +0 -1
- package/dist/shared/config/index.d.ts +0 -1
- package/dist/shared/config/index.js +0 -9
- package/dist/shared/config/index.js.map +0 -1
- package/dist/shared/redis/redis-connection-factory.d.ts +0 -66
- package/dist/shared/redis/redis-connection-factory.js +0 -113
- package/dist/shared/redis/redis-connection-factory.js.map +0 -1
- /package/dist/command-bus/{config/auto-config-optimizer.spec.d.ts → serialization/msgpack-serializer.spec.d.ts} +0 -0
- /package/dist/command-bus/{job/job-options-builder.spec.d.ts → transport/consumer-loop.spec.d.ts} +0 -0
- /package/dist/command-bus/{job/job-processor.spec.d.ts → transport/message-processor.spec.d.ts} +0 -0
- /package/dist/command-bus/{queue/queue-manager.spec.d.ts → transport/pending-recovery.spec.d.ts} +0 -0
- /package/dist/command-bus/{rpc/payload-compression.service.spec.d.ts → transport/redis-codec.spec.d.ts} +0 -0
- /package/dist/command-bus/{rpc/rpc-coordinator.spec.d.ts → transport/redis-streams-transport.spec.d.ts} +0 -0
- /package/dist/command-bus/{rpc/rpc-job-cancellation.service.spec.d.ts → transport/rpc-handler.spec.d.ts} +0 -0
- /package/dist/command-bus/{worker/worker-benchmark.spec.d.ts → transport/stream-consumer.spec.d.ts} +0 -0
- /package/dist/command-bus/{worker/worker-orchestrator.spec.d.ts → transport/stream-producer.spec.d.ts} +0 -0
- /package/dist/shared/{config/base-config.spec.d.ts → redis/connection-pool.spec.d.ts} +0 -0
|
@@ -0,0 +1,284 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const stream_consumer_1 = require("./stream-consumer");
|
|
13
|
+
const redis_codec_1 = require("./redis-codec");
|
|
14
|
+
/**
|
|
15
|
+
* Mock helpers
|
|
16
|
+
*/
|
|
17
|
+
function createMockLogger() {
|
|
18
|
+
return {
|
|
19
|
+
log: jest.fn(),
|
|
20
|
+
error: jest.fn(),
|
|
21
|
+
warn: jest.fn(),
|
|
22
|
+
debug: jest.fn(),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createMockSerializer() {
|
|
26
|
+
return {
|
|
27
|
+
serialize: jest.fn((data) => Buffer.from(JSON.stringify(data))),
|
|
28
|
+
deserialize: jest.fn((buf) => JSON.parse(buf.toString())),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function createMockConnection() {
|
|
32
|
+
const pendingRejects = [];
|
|
33
|
+
return {
|
|
34
|
+
xadd: jest.fn().mockResolvedValue('1700000000000-0'),
|
|
35
|
+
xreadgroup: jest.fn().mockImplementation(() => new Promise((_resolve, reject) => {
|
|
36
|
+
pendingRejects.push(reject);
|
|
37
|
+
})),
|
|
38
|
+
xack: jest.fn().mockResolvedValue(1),
|
|
39
|
+
xgroup: jest.fn().mockResolvedValue('OK'),
|
|
40
|
+
xtrim: jest.fn().mockResolvedValue(0),
|
|
41
|
+
on: jest.fn(),
|
|
42
|
+
disconnect: jest.fn().mockImplementation(() => {
|
|
43
|
+
const disconnectError = new Error('Connection is closed.');
|
|
44
|
+
while (pendingRejects.length > 0) {
|
|
45
|
+
const reject = pendingRejects.shift();
|
|
46
|
+
if (reject)
|
|
47
|
+
reject(disconnectError);
|
|
48
|
+
}
|
|
49
|
+
}),
|
|
50
|
+
pipeline: jest.fn().mockReturnValue({
|
|
51
|
+
xack: jest.fn().mockReturnThis(),
|
|
52
|
+
xtrim: jest.fn().mockReturnThis(),
|
|
53
|
+
exec: jest.fn().mockResolvedValue([
|
|
54
|
+
[null, 1],
|
|
55
|
+
[null, 0],
|
|
56
|
+
]),
|
|
57
|
+
}),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function createMockPool() {
|
|
61
|
+
const conn = createMockConnection();
|
|
62
|
+
return {
|
|
63
|
+
pool: {
|
|
64
|
+
next: jest.fn().mockReturnValue(conn),
|
|
65
|
+
createDedicated: jest.fn().mockReturnValue(conn),
|
|
66
|
+
},
|
|
67
|
+
conn,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
describe('StreamConsumer', () => {
|
|
71
|
+
let consumer;
|
|
72
|
+
let logger;
|
|
73
|
+
let serializer;
|
|
74
|
+
let mockConn;
|
|
75
|
+
let mockPool;
|
|
76
|
+
const rpcRespond = jest.fn().mockResolvedValue(undefined);
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
jest.clearAllMocks();
|
|
79
|
+
logger = createMockLogger();
|
|
80
|
+
serializer = createMockSerializer();
|
|
81
|
+
const poolMock = createMockPool();
|
|
82
|
+
mockPool = poolMock.pool;
|
|
83
|
+
mockConn = poolMock.conn;
|
|
84
|
+
consumer = new stream_consumer_1.StreamConsumer({
|
|
85
|
+
pool: mockPool,
|
|
86
|
+
serializer,
|
|
87
|
+
logger,
|
|
88
|
+
consumerId: 'test-consumer',
|
|
89
|
+
batchSize: 10,
|
|
90
|
+
concurrency: 5,
|
|
91
|
+
maxRetained: 10000,
|
|
92
|
+
rpcRespond,
|
|
93
|
+
staleThreshold: 100, // Niski threshold dla testów (100ms)
|
|
94
|
+
sweepInterval: 0, // Brak throttle w testach — sweep na każdą wiadomość
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
afterEach(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
+
consumer.running = false;
|
|
99
|
+
consumer.closeConnections();
|
|
100
|
+
yield consumer.awaitLoops();
|
|
101
|
+
}));
|
|
102
|
+
describe('processMessage()', () => {
|
|
103
|
+
it('powinien przetworzyć wiadomość i wywołać handler', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
104
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
105
|
+
const testPayload = redis_codec_1.RedisCodec.encode(Buffer.from('test-data'));
|
|
106
|
+
const fields = ['data', testPayload];
|
|
107
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-1', fields, handler);
|
|
108
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
109
|
+
expect(handler).toHaveBeenCalledWith(expect.any(Buffer));
|
|
110
|
+
}));
|
|
111
|
+
it('powinien zdeduplikować wiadomości przetwarzane równolegle', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
+
let resolveHandler;
|
|
113
|
+
const handlerPromise = new Promise((resolve) => {
|
|
114
|
+
resolveHandler = resolve;
|
|
115
|
+
});
|
|
116
|
+
const handler = jest.fn().mockReturnValue(handlerPromise);
|
|
117
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
118
|
+
// Rozpocznij pierwsze przetwarzanie (nie kończy się)
|
|
119
|
+
const firstProcessing = consumer.processMessage('cmd:Test', 'workers', 'msg-dup', fields, handler);
|
|
120
|
+
// Drugie przetwarzanie tego samego ID — powinno być pominięte
|
|
121
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-dup', fields, handler);
|
|
122
|
+
// Handler powinien być wywołany tylko RAZ
|
|
123
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
124
|
+
// Cleanup
|
|
125
|
+
resolveHandler();
|
|
126
|
+
yield firstProcessing;
|
|
127
|
+
}));
|
|
128
|
+
it('powinien XACK wiadomość po przetworzeniu', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
129
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
130
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
131
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-1', fields, handler);
|
|
132
|
+
expect(mockConn.xack).toHaveBeenCalledWith('cmd:Test', 'workers', 'msg-1');
|
|
133
|
+
}));
|
|
134
|
+
it('powinien obsłużyć wiadomość z pustym fields array (H4)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
135
|
+
const handler = jest.fn();
|
|
136
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-empty', [], handler);
|
|
137
|
+
// Handler NIE powinien być wywołany
|
|
138
|
+
expect(handler).not.toHaveBeenCalled();
|
|
139
|
+
// Powinien zalogować warning
|
|
140
|
+
expect(logger.warn).toHaveBeenCalledWith('Nieprawidłowa wiadomość — brak danych', expect.objectContaining({ messageId: 'msg-empty' }));
|
|
141
|
+
// Powinien XACK (żeby wiadomość nie wracała)
|
|
142
|
+
expect(mockConn.xack).toHaveBeenCalledWith('cmd:Test', 'workers', 'msg-empty');
|
|
143
|
+
}));
|
|
144
|
+
it('powinien obsłużyć wiadomość z jednym elementem w fields (H4)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
145
|
+
const handler = jest.fn();
|
|
146
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-odd', ['key-only'], handler);
|
|
147
|
+
expect(handler).not.toHaveBeenCalled();
|
|
148
|
+
expect(logger.warn).toHaveBeenCalledWith('Nieprawidłowa wiadomość — brak danych', expect.objectContaining({ messageId: 'msg-odd' }));
|
|
149
|
+
}));
|
|
150
|
+
it('powinien obsłużyć wiadomość bez pola data (H4)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
151
|
+
const handler = jest.fn();
|
|
152
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-nodata', ['other', 'value'], handler);
|
|
153
|
+
expect(handler).not.toHaveBeenCalled();
|
|
154
|
+
expect(logger.warn).toHaveBeenCalledWith('Wiadomość bez pola data', expect.objectContaining({ messageId: 'msg-nodata' }));
|
|
155
|
+
}));
|
|
156
|
+
it('powinien obsłużyć nieparzystą liczbę elementów w fields (H4)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
158
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data')), 'extra-key'];
|
|
159
|
+
// Nie powinien crashować — bounds check w pętli
|
|
160
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-odd-fields', fields, handler);
|
|
161
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
162
|
+
}));
|
|
163
|
+
it('powinien zalogować błąd gdy handler rzuci wyjątek', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
+
const handler = jest.fn().mockRejectedValue(new Error('Handler error'));
|
|
165
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
166
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-err', fields, handler);
|
|
167
|
+
expect(logger.error).toHaveBeenCalledWith('Błąd przetwarzania wiadomości', expect.objectContaining({
|
|
168
|
+
messageId: 'msg-err',
|
|
169
|
+
error: 'Handler error',
|
|
170
|
+
}));
|
|
171
|
+
}));
|
|
172
|
+
it('powinien usunąć messageId z processing po zakończeniu (nawet przy błędzie)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
173
|
+
const handler = jest.fn().mockRejectedValue(new Error('fail'));
|
|
174
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
175
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-cleanup', fields, handler);
|
|
176
|
+
// Po zakończeniu messageId powinien być usunięty z processing
|
|
177
|
+
expect(consumer['processing'].has('msg-cleanup')).toBe(false);
|
|
178
|
+
}));
|
|
179
|
+
});
|
|
180
|
+
describe('stale processing sweep (H1)', () => {
|
|
181
|
+
it('powinien usunąć stale wpisy z processing Map', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
182
|
+
// Dodaj stale wpis ręcznie (timestamp w przeszłości)
|
|
183
|
+
consumer['processing'].set('msg-stale', Date.now() - 200); // 200ms > 100ms threshold
|
|
184
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
185
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
186
|
+
// processMessage wywołuje sweepStaleProcessing na początku
|
|
187
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-new', fields, handler);
|
|
188
|
+
// Stale wpis powinien być usunięty
|
|
189
|
+
expect(consumer['processing'].has('msg-stale')).toBe(false);
|
|
190
|
+
// Powinien zalogować warning
|
|
191
|
+
expect(logger.warn).toHaveBeenCalledWith('Usunięto stale wpis z processing Map', expect.objectContaining({ messageId: 'msg-stale' }));
|
|
192
|
+
}));
|
|
193
|
+
it('powinien pozwolić na retry wiadomości po sweep', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
194
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
195
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
196
|
+
// Dodaj stale wpis
|
|
197
|
+
consumer['processing'].set('msg-retry', Date.now() - 200);
|
|
198
|
+
// Po sweep, ta sama wiadomość powinna być przetworzona ponownie
|
|
199
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-retry', fields, handler);
|
|
200
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
201
|
+
}));
|
|
202
|
+
it('nie powinien usuwać świeżych wpisów z processing Map', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
203
|
+
// Dodaj świeży wpis (timestamp teraz)
|
|
204
|
+
consumer['processing'].set('msg-fresh', Date.now());
|
|
205
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
206
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
207
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-other', fields, handler);
|
|
208
|
+
// Świeży wpis powinien zostać
|
|
209
|
+
expect(consumer['processing'].has('msg-fresh')).toBe(true);
|
|
210
|
+
}));
|
|
211
|
+
});
|
|
212
|
+
describe('XTRIM per-stream (H2)', () => {
|
|
213
|
+
it('powinien zliczać XTRIM niezależnie per strumień', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
214
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
215
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
216
|
+
// 9 wiadomości na stream A — nie powinno triggerować XTRIM (batchSize=10)
|
|
217
|
+
for (let i = 0; i < 9; i++) {
|
|
218
|
+
yield consumer.processMessage('cmd:StreamA', 'workers', `a-${i}`, fields, handler);
|
|
219
|
+
}
|
|
220
|
+
// 1 wiadomość na stream B
|
|
221
|
+
yield consumer.processMessage('cmd:StreamB', 'workers', 'b-0', fields, handler);
|
|
222
|
+
// Pipeline (XACK+XTRIM) NIE powinien być wywołany — żaden stream nie osiągnął batchSize
|
|
223
|
+
// Stream A: 9, Stream B: 1
|
|
224
|
+
// Pipeline jest wywoływany dopiero przy batchSize (10)
|
|
225
|
+
const xackCalls = mockConn.xack.mock.calls;
|
|
226
|
+
expect(xackCalls.length).toBe(10);
|
|
227
|
+
// 10. wiadomość na stream A — powinno triggerować XTRIM tylko dla stream A
|
|
228
|
+
yield consumer.processMessage('cmd:StreamA', 'workers', 'a-9', fields, handler);
|
|
229
|
+
// Pipeline powinien być wywołany dla stream A
|
|
230
|
+
expect(mockConn.pipeline).toHaveBeenCalled();
|
|
231
|
+
}));
|
|
232
|
+
it('powinien wykonać XTRIM co batchSize wiadomości', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
233
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
234
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('data'))];
|
|
235
|
+
// Wyślij dokładnie batchSize (10) wiadomości
|
|
236
|
+
for (let i = 0; i < 10; i++) {
|
|
237
|
+
yield consumer.processMessage('cmd:Test', 'workers', `msg-${i}`, fields, handler);
|
|
238
|
+
}
|
|
239
|
+
// Pipeline powinien być wywołany dokładnie raz (10. wiadomość)
|
|
240
|
+
expect(mockConn.pipeline).toHaveBeenCalledTimes(1);
|
|
241
|
+
}));
|
|
242
|
+
});
|
|
243
|
+
describe('RPC detection', () => {
|
|
244
|
+
it('powinien wykryć RPC wiadomość przez marker i odpowiedzieć', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
245
|
+
const handler = jest.fn().mockResolvedValue('result-42');
|
|
246
|
+
const envelope = {
|
|
247
|
+
commandData: redis_codec_1.RedisCodec.encode(Buffer.from('cmd-data')),
|
|
248
|
+
rpc: { correlationId: 'corr-1', responseKey: 'rpc:res:corr-1' },
|
|
249
|
+
};
|
|
250
|
+
const envelopePayload = redis_codec_1.RedisCodec.encode(Buffer.from(JSON.stringify(envelope)));
|
|
251
|
+
const fields = ['data', envelopePayload, 'rpc', '1'];
|
|
252
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-rpc', fields, handler);
|
|
253
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
254
|
+
expect(rpcRespond).toHaveBeenCalledWith('rpc:res:corr-1', expect.any(Buffer), 60);
|
|
255
|
+
}));
|
|
256
|
+
it('powinien przetworzyć zwykłą komendę bez rpcRespond', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
257
|
+
const handler = jest.fn().mockResolvedValue('ok');
|
|
258
|
+
const fields = ['data', redis_codec_1.RedisCodec.encode(Buffer.from('normal-data'))];
|
|
259
|
+
yield consumer.processMessage('cmd:Test', 'workers', 'msg-normal', fields, handler);
|
|
260
|
+
expect(handler).toHaveBeenCalledTimes(1);
|
|
261
|
+
expect(rpcRespond).not.toHaveBeenCalled();
|
|
262
|
+
}));
|
|
263
|
+
});
|
|
264
|
+
describe('consume()', () => {
|
|
265
|
+
it('powinien utworzyć consumer group i rozpocząć nasłuchiwanie', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
266
|
+
const handler = jest.fn();
|
|
267
|
+
yield consumer.consume('cmd:Test', 'workers', handler);
|
|
268
|
+
expect(mockConn.xgroup).toHaveBeenCalledWith('CREATE', 'cmd:Test', 'workers', '0', 'MKSTREAM');
|
|
269
|
+
expect(consumer.consumerCount).toBe(1);
|
|
270
|
+
expect(consumer['consumerLoopPromises'].length).toBe(1);
|
|
271
|
+
}));
|
|
272
|
+
it('powinien obsłużyć BUSYGROUP (grupa już istnieje)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
273
|
+
mockConn.xgroup.mockRejectedValueOnce(new Error('BUSYGROUP Consumer Group name already exists'));
|
|
274
|
+
const handler = jest.fn();
|
|
275
|
+
// Nie powinien rzucić błędu
|
|
276
|
+
yield consumer.consume('cmd:Test', 'workers', handler);
|
|
277
|
+
}));
|
|
278
|
+
it('powinien rzucić błąd dla innych błędów xgroup', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
279
|
+
mockConn.xgroup.mockRejectedValueOnce(new Error('NOPERM access denied'));
|
|
280
|
+
yield expect(consumer.consume('cmd:Test', 'workers', jest.fn())).rejects.toThrow('NOPERM access denied');
|
|
281
|
+
}));
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
//# sourceMappingURL=stream-consumer.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-consumer.spec.js","sourceRoot":"","sources":["../../../src/command-bus/transport/stream-consumer.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type RedisConnectionPool from '../../shared/redis/connection-pool';
|
|
2
|
+
import type { IStreamProducer } from './transport.interface';
|
|
3
|
+
/**
|
|
4
|
+
* Producent strumienia Redis — odpowiada za dodawanie wiadomości do strumieni
|
|
5
|
+
* Jedna odpowiedzialność: enqueue (XADD) z kodowaniem RedisCodec
|
|
6
|
+
*/
|
|
7
|
+
export declare class StreamProducer implements IStreamProducer {
|
|
8
|
+
private readonly pool;
|
|
9
|
+
constructor(pool: RedisConnectionPool);
|
|
10
|
+
/**
|
|
11
|
+
* Dodaje komendę do strumienia (fire-and-forget)
|
|
12
|
+
* XADD = 1 natywne polecenie Redis, DragonflyDB przetwarza wielowątkowo
|
|
13
|
+
*/
|
|
14
|
+
enqueue(streamName: string, data: Buffer): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Dodaje wiele komend w jednym pipeline
|
|
17
|
+
* DragonflyDB przetwarza pipeline równolegle na wielu wątkach
|
|
18
|
+
*/
|
|
19
|
+
enqueueBatch(entries: Array<{
|
|
20
|
+
streamName: string;
|
|
21
|
+
data: Buffer;
|
|
22
|
+
}>): Promise<string[]>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.StreamProducer = void 0;
|
|
13
|
+
const redis_codec_1 = require("./redis-codec");
|
|
14
|
+
/**
|
|
15
|
+
* Producent strumienia Redis — odpowiada za dodawanie wiadomości do strumieni
|
|
16
|
+
* Jedna odpowiedzialność: enqueue (XADD) z kodowaniem RedisCodec
|
|
17
|
+
*/
|
|
18
|
+
class StreamProducer {
|
|
19
|
+
constructor(pool) {
|
|
20
|
+
this.pool = pool;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Dodaje komendę do strumienia (fire-and-forget)
|
|
24
|
+
* XADD = 1 natywne polecenie Redis, DragonflyDB przetwarza wielowątkowo
|
|
25
|
+
*/
|
|
26
|
+
enqueue(streamName, data) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const conn = this.pool.next();
|
|
29
|
+
const messageId = yield conn.xadd(streamName, '*', 'data', redis_codec_1.RedisCodec.encode(data));
|
|
30
|
+
return messageId;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Dodaje wiele komend w jednym pipeline
|
|
35
|
+
* DragonflyDB przetwarza pipeline równolegle na wielu wątkach
|
|
36
|
+
*/
|
|
37
|
+
enqueueBatch(entries) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
var _a;
|
|
40
|
+
if (entries.length === 0)
|
|
41
|
+
return [];
|
|
42
|
+
const conn = this.pool.next();
|
|
43
|
+
const pipeline = conn.pipeline();
|
|
44
|
+
for (const entry of entries) {
|
|
45
|
+
pipeline.xadd(entry.streamName, '*', 'data', redis_codec_1.RedisCodec.encode(entry.data));
|
|
46
|
+
}
|
|
47
|
+
const results = yield pipeline.exec();
|
|
48
|
+
if (!results)
|
|
49
|
+
return [];
|
|
50
|
+
// H3: Wykrywanie pipeline errors — zapobiega silent data loss
|
|
51
|
+
const failedIndices = [];
|
|
52
|
+
const messageIds = [];
|
|
53
|
+
for (let i = 0; i < results.length; i++) {
|
|
54
|
+
const [error, value] = results[i];
|
|
55
|
+
if (error) {
|
|
56
|
+
failedIndices.push(i);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
messageIds.push((_a = value) !== null && _a !== void 0 ? _a : '');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (failedIndices.length > 0) {
|
|
63
|
+
throw new Error(`Błąd pipeline XADD — ${failedIndices.length}/${results.length} operacji nie powiodło się (indeksy: ${failedIndices.join(', ')})`);
|
|
64
|
+
}
|
|
65
|
+
return messageIds;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.StreamProducer = StreamProducer;
|
|
70
|
+
//# sourceMappingURL=stream-producer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-producer.js","sourceRoot":"","sources":["../../../src/command-bus/transport/stream-producer.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,+CAA2C;AAE3C;;;GAGG;AACH,MAAa,cAAc;IACzB,YAA6B,IAAyB;QAAzB,SAAI,GAAJ,IAAI,CAAqB;IAAG,CAAC;IAE1D;;;OAGG;IACU,OAAO,CAAC,UAAkB,EAAE,IAAY;;YACnD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,wBAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;YACpF,OAAO,SAAmB,CAAC;QAC7B,CAAC;KAAA;IAED;;;OAGG;IACU,YAAY,CACvB,OAAoD;;;YAEpD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAEpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAEjC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,wBAAU,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9E,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,CAAC;YAExB,8DAA8D;YAC9D,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,MAAM,UAAU,GAAa,EAAE,CAAC;YAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAClC,IAAI,KAAK,EAAE,CAAC;oBACV,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACxB,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,IAAI,CAAC,MAAC,KAAgB,mCAAI,EAAE,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YAED,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,wBAAwB,aAAa,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,wCAAwC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAClI,CAAC;YACJ,CAAC;YAED,OAAO,UAAU,CAAC;QACpB,CAAC;KAAA;CACF;AArDD,wCAqDC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const stream_producer_1 = require("./stream-producer");
|
|
13
|
+
const redis_codec_1 = require("./redis-codec");
|
|
14
|
+
/**
|
|
15
|
+
* Mock puli połączeń Redis
|
|
16
|
+
*/
|
|
17
|
+
function createMockPool() {
|
|
18
|
+
const mockPipeline = {
|
|
19
|
+
xadd: jest.fn().mockReturnThis(),
|
|
20
|
+
exec: jest.fn().mockResolvedValue(null),
|
|
21
|
+
};
|
|
22
|
+
const mockConn = {
|
|
23
|
+
xadd: jest.fn().mockResolvedValue('1700000000000-0'),
|
|
24
|
+
pipeline: jest.fn().mockReturnValue(mockPipeline),
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
pool: { next: jest.fn().mockReturnValue(mockConn) },
|
|
28
|
+
conn: mockConn,
|
|
29
|
+
pipeline: mockPipeline,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
describe('StreamProducer', () => {
|
|
33
|
+
describe('enqueue()', () => {
|
|
34
|
+
it('powinien dodać komendę do strumienia przez XADD', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
const { pool, conn } = createMockPool();
|
|
36
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
37
|
+
const data = Buffer.from('test-data');
|
|
38
|
+
const messageId = yield producer.enqueue('cmd:TestCommand', data);
|
|
39
|
+
expect(conn.xadd).toHaveBeenCalledWith('cmd:TestCommand', '*', 'data', redis_codec_1.RedisCodec.encode(data));
|
|
40
|
+
expect(messageId).toBe('1700000000000-0');
|
|
41
|
+
}));
|
|
42
|
+
it('powinien używać połączenia z puli', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
const { pool } = createMockPool();
|
|
44
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
45
|
+
yield producer.enqueue('cmd:Test', Buffer.from('data'));
|
|
46
|
+
expect(pool.next).toHaveBeenCalledTimes(1);
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
describe('enqueueBatch()', () => {
|
|
50
|
+
it('powinien zwrócić pustą tablicę dla pustego wejścia', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
51
|
+
const { pool } = createMockPool();
|
|
52
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
53
|
+
const ids = yield producer.enqueueBatch([]);
|
|
54
|
+
expect(ids).toEqual([]);
|
|
55
|
+
}));
|
|
56
|
+
it('powinien zwrócić wszystkie IDs gdy brak błędów', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
const { pool, pipeline } = createMockPool();
|
|
58
|
+
pipeline.exec.mockResolvedValue([
|
|
59
|
+
[null, '1700000000000-0'],
|
|
60
|
+
[null, '1700000000001-0'],
|
|
61
|
+
[null, '1700000000002-0'],
|
|
62
|
+
]);
|
|
63
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
64
|
+
const entries = [
|
|
65
|
+
{ streamName: 'cmd:A', data: Buffer.from('a') },
|
|
66
|
+
{ streamName: 'cmd:B', data: Buffer.from('b') },
|
|
67
|
+
{ streamName: 'cmd:C', data: Buffer.from('c') },
|
|
68
|
+
];
|
|
69
|
+
const ids = yield producer.enqueueBatch(entries);
|
|
70
|
+
expect(ids).toEqual(['1700000000000-0', '1700000000001-0', '1700000000002-0']);
|
|
71
|
+
}));
|
|
72
|
+
it('powinien użyć pipeline dla wielu komend', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const { pool, pipeline, conn } = createMockPool();
|
|
74
|
+
pipeline.exec.mockResolvedValue([
|
|
75
|
+
[null, '1700000000000-0'],
|
|
76
|
+
[null, '1700000000001-0'],
|
|
77
|
+
]);
|
|
78
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
79
|
+
yield producer.enqueueBatch([
|
|
80
|
+
{ streamName: 'cmd:A', data: Buffer.from('a') },
|
|
81
|
+
{ streamName: 'cmd:B', data: Buffer.from('b') },
|
|
82
|
+
]);
|
|
83
|
+
expect(conn.pipeline).toHaveBeenCalledTimes(1);
|
|
84
|
+
expect(pipeline.xadd).toHaveBeenCalledTimes(2);
|
|
85
|
+
expect(pipeline.exec).toHaveBeenCalledTimes(1);
|
|
86
|
+
}));
|
|
87
|
+
it('powinien rzucić błąd gdy pipeline zawiera errory (H3)', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
+
const { pool, pipeline } = createMockPool();
|
|
89
|
+
pipeline.exec.mockResolvedValue([
|
|
90
|
+
[null, '1700000000000-0'],
|
|
91
|
+
[new Error('WRONGTYPE'), null],
|
|
92
|
+
[null, '1700000000002-0'],
|
|
93
|
+
]);
|
|
94
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
95
|
+
const entries = [
|
|
96
|
+
{ streamName: 'cmd:A', data: Buffer.from('a') },
|
|
97
|
+
{ streamName: 'cmd:B', data: Buffer.from('b') },
|
|
98
|
+
{ streamName: 'cmd:C', data: Buffer.from('c') },
|
|
99
|
+
];
|
|
100
|
+
yield expect(producer.enqueueBatch(entries)).rejects.toThrow('Błąd pipeline XADD — 1/3 operacji nie powiodło się');
|
|
101
|
+
}));
|
|
102
|
+
it('powinien rzucić błąd z indeksami failujących operacji', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
const { pool, pipeline } = createMockPool();
|
|
104
|
+
pipeline.exec.mockResolvedValue([
|
|
105
|
+
[new Error('ERR1'), null],
|
|
106
|
+
[null, '1700000000001-0'],
|
|
107
|
+
[new Error('ERR2'), null],
|
|
108
|
+
]);
|
|
109
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
110
|
+
yield expect(producer.enqueueBatch([
|
|
111
|
+
{ streamName: 'cmd:A', data: Buffer.from('a') },
|
|
112
|
+
{ streamName: 'cmd:B', data: Buffer.from('b') },
|
|
113
|
+
{ streamName: 'cmd:C', data: Buffer.from('c') },
|
|
114
|
+
])).rejects.toThrow('indeksy: 0, 2');
|
|
115
|
+
}));
|
|
116
|
+
it('powinien zwrócić pustą tablicę gdy exec zwraca null', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
117
|
+
const { pool, pipeline } = createMockPool();
|
|
118
|
+
pipeline.exec.mockResolvedValue(null);
|
|
119
|
+
const producer = new stream_producer_1.StreamProducer(pool);
|
|
120
|
+
const ids = yield producer.enqueueBatch([{ streamName: 'cmd:A', data: Buffer.from('a') }]);
|
|
121
|
+
expect(ids).toEqual([]);
|
|
122
|
+
}));
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
//# sourceMappingURL=stream-producer.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-producer.spec.js","sourceRoot":"","sources":["../../../src/command-bus/transport/stream-producer.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handler konsumenta strumienia Redis
|
|
3
|
+
* Otrzymuje surowe dane (Buffer) i zwraca wynik przetwarzania
|
|
4
|
+
*
|
|
5
|
+
* @param data - Surowe dane wiadomości (Buffer)
|
|
6
|
+
* @returns Wynik przetwarzania (lub void dla fire-and-forget)
|
|
7
|
+
*/
|
|
8
|
+
export type ConsumerHandler = (data: Buffer) => Promise<unknown>;
|
|
9
|
+
/**
|
|
10
|
+
* Metadane RPC dołączane do wiadomości w strumieniu
|
|
11
|
+
* Umożliwiają powiązanie odpowiedzi z żądaniem
|
|
12
|
+
*/
|
|
13
|
+
export interface RpcMessageMetadata {
|
|
14
|
+
/** Unikalny identyfikator korelacji (UUID v4) */
|
|
15
|
+
correlationId: string;
|
|
16
|
+
/** Klucz Redis listy na którą worker wyśle odpowiedź (LPUSH) */
|
|
17
|
+
responseKey: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Producent strumienia — dodaje wiadomości do Redis Streams
|
|
21
|
+
*/
|
|
22
|
+
export interface IStreamProducer {
|
|
23
|
+
/**
|
|
24
|
+
* Dodaje komendę do strumienia (fire-and-forget)
|
|
25
|
+
* @param streamName - Nazwa strumienia Redis
|
|
26
|
+
* @param data - Surowe dane do wysłania
|
|
27
|
+
* @returns ID wiadomości w strumieniu
|
|
28
|
+
*/
|
|
29
|
+
enqueue(streamName: string, data: Buffer): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Dodaje wiele komend naraz z użyciem pipelining
|
|
32
|
+
* @param entries - Tablica wpisów do dodania
|
|
33
|
+
* @returns Tablica ID wiadomości w strumieniach
|
|
34
|
+
*/
|
|
35
|
+
enqueueBatch(entries: Array<{
|
|
36
|
+
streamName: string;
|
|
37
|
+
data: Buffer;
|
|
38
|
+
}>): Promise<string[]>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Konsument strumienia — czyta wiadomości z Redis Streams via consumer groups
|
|
42
|
+
*/
|
|
43
|
+
export interface IStreamConsumer {
|
|
44
|
+
/**
|
|
45
|
+
* Rejestruje konsumenta dla strumienia z consumer group
|
|
46
|
+
* @param streamName - Nazwa strumienia Redis
|
|
47
|
+
* @param groupName - Nazwa grupy konsumentów
|
|
48
|
+
* @param handler - Handler przetwarzający wiadomości
|
|
49
|
+
*/
|
|
50
|
+
consume(streamName: string, groupName: string, handler: ConsumerHandler): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Transport RPC — request/response przez Redis Streams + LPUSH/BRPOP
|
|
54
|
+
*/
|
|
55
|
+
export interface IRpcTransport {
|
|
56
|
+
/**
|
|
57
|
+
* RPC: wysyła request do strumienia i czeka na odpowiedź via BRPOP
|
|
58
|
+
* @param commandName - Nazwa komendy (używana jako nazwa strumienia)
|
|
59
|
+
* @param data - Surowe dane żądania
|
|
60
|
+
* @param timeout - Timeout w milisekundach
|
|
61
|
+
* @returns Buffer z odpowiedzią
|
|
62
|
+
*/
|
|
63
|
+
rpcCall(commandName: string, data: Buffer, timeout: number): Promise<Buffer>;
|
|
64
|
+
/**
|
|
65
|
+
* RPC: odpowiada na request przez LPUSH + EXPIRE
|
|
66
|
+
* @param responseKey - Klucz Redis listy na którą wysłać odpowiedź
|
|
67
|
+
* @param data - Surowe dane odpowiedzi
|
|
68
|
+
* @param ttl - Czas życia klucza w sekundach (safety net)
|
|
69
|
+
*/
|
|
70
|
+
rpcRespond(responseKey: string, data: Buffer, ttl: number): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Zarządzanie cyklem życia — graceful shutdown
|
|
74
|
+
*/
|
|
75
|
+
export interface IClosable {
|
|
76
|
+
/** Zamyka zasób i wszystkie połączenia */
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Pełny interfejs transportu dla CommandBus
|
|
81
|
+
* Kompozycja segregowanych interfejsów (ISP)
|
|
82
|
+
*
|
|
83
|
+
* Odpowiada wyłącznie za przesyłanie surowych danych (Buffer)
|
|
84
|
+
* Serializacja/deserializacja jest odpowiedzialnością wyższej warstwy
|
|
85
|
+
*/
|
|
86
|
+
export interface ITransport extends IStreamProducer, IStreamConsumer, IRpcTransport, IClosable {
|
|
87
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.interface.js","sourceRoot":"","sources":["../../../src/command-bus/transport/transport.interface.ts"],"names":[],"mappings":""}
|