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
@@ -0,0 +1,157 @@
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 rpc_handler_1 = require("./rpc-handler");
13
+ const redis_codec_1 = require("./redis-codec");
14
+ /**
15
+ * Mock serializera — JSON roundtrip
16
+ */
17
+ function createMockSerializer() {
18
+ return {
19
+ serialize: jest.fn((data) => Buffer.from(JSON.stringify(data))),
20
+ deserialize: jest.fn((buf) => JSON.parse(buf.toString())),
21
+ };
22
+ }
23
+ /**
24
+ * Mock połączenia Redis
25
+ */
26
+ function createMockConnection() {
27
+ return {
28
+ xadd: jest.fn().mockResolvedValue('1700000000000-0'),
29
+ del: jest.fn().mockResolvedValue(1),
30
+ expire: jest.fn().mockResolvedValue(1),
31
+ brpop: jest.fn().mockResolvedValue(null),
32
+ lpush: jest.fn().mockResolvedValue(1),
33
+ pipeline: jest.fn().mockReturnValue({
34
+ lpush: jest.fn().mockReturnThis(),
35
+ expire: jest.fn().mockReturnThis(),
36
+ exec: jest.fn().mockResolvedValue([
37
+ [null, 1],
38
+ [null, 1],
39
+ ]),
40
+ }),
41
+ };
42
+ }
43
+ function createMockPool() {
44
+ const conn = createMockConnection();
45
+ return {
46
+ pool: { next: jest.fn().mockReturnValue(conn) },
47
+ conn,
48
+ };
49
+ }
50
+ function createMockRpcPool() {
51
+ const rpcConn = createMockConnection();
52
+ return {
53
+ rpcPool: {
54
+ acquire: jest.fn().mockResolvedValue(rpcConn),
55
+ release: jest.fn(),
56
+ },
57
+ rpcConn,
58
+ };
59
+ }
60
+ describe('RpcHandler', () => {
61
+ let handler;
62
+ let mockConn;
63
+ let rpcConn;
64
+ let mockPool;
65
+ let mockRpcPool;
66
+ let serializer;
67
+ beforeEach(() => {
68
+ jest.clearAllMocks();
69
+ const poolMock = createMockPool();
70
+ const rpcPoolMock = createMockRpcPool();
71
+ mockPool = poolMock.pool;
72
+ mockConn = poolMock.conn;
73
+ mockRpcPool = rpcPoolMock.rpcPool;
74
+ rpcConn = rpcPoolMock.rpcConn;
75
+ serializer = createMockSerializer();
76
+ handler = new rpc_handler_1.RpcHandler(mockPool, mockRpcPool, serializer);
77
+ });
78
+ describe('rpcCall()', () => {
79
+ it('powinien wysłać komendę do strumienia i czekać na odpowiedź', () => __awaiter(void 0, void 0, void 0, function* () {
80
+ const responseData = Buffer.from(JSON.stringify({ result: 42 }));
81
+ rpcConn.brpop.mockResolvedValue(['rpc:res:test', redis_codec_1.RedisCodec.encode(responseData)]);
82
+ const result = yield handler.rpcCall('TestCommand', Buffer.from('request'), 5000);
83
+ // Powinien wysłać XADD z markerem rpc
84
+ expect(mockConn.xadd).toHaveBeenCalledWith('cmd:TestCommand', '*', 'data', expect.any(String), 'rpc', '1');
85
+ // Powinien pobrać i zwolnić połączenie RPC
86
+ expect(mockRpcPool.acquire).toHaveBeenCalled();
87
+ expect(mockRpcPool.release).toHaveBeenCalled();
88
+ expect(result).toBeInstanceOf(Buffer);
89
+ }));
90
+ it('powinien rzucić timeout gdy BRPOP zwraca null', () => __awaiter(void 0, void 0, void 0, function* () {
91
+ rpcConn.brpop.mockResolvedValue(null);
92
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 1000)).rejects.toThrow('RPC timeout dla komendy TestCommand (1000ms)');
93
+ }));
94
+ it('powinien zwolnić połączenie RPC nawet przy timeout', () => __awaiter(void 0, void 0, void 0, function* () {
95
+ rpcConn.brpop.mockResolvedValue(null);
96
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 1000)).rejects.toThrow();
97
+ expect(mockRpcPool.release).toHaveBeenCalledWith(rpcConn);
98
+ }));
99
+ it('powinien await DEL na timeout (C2)', () => __awaiter(void 0, void 0, void 0, function* () {
100
+ rpcConn.brpop.mockResolvedValue(null);
101
+ mockConn.del.mockResolvedValue(1);
102
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 1000)).rejects.toThrow();
103
+ expect(mockConn.del).toHaveBeenCalled();
104
+ }));
105
+ it('powinien ustawić EXPIRE jako fallback gdy DEL failuje (C2)', () => __awaiter(void 0, void 0, void 0, function* () {
106
+ rpcConn.brpop.mockResolvedValue(null);
107
+ mockConn.del.mockRejectedValue(new Error('Connection lost'));
108
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 1000)).rejects.toThrow('RPC timeout');
109
+ expect(mockConn.del).toHaveBeenCalled();
110
+ expect(mockConn.expire).toHaveBeenCalledWith(expect.stringContaining('rpc:res:'), 120);
111
+ }));
112
+ it('nie powinien rzucać gdy zarówno DEL jak i EXPIRE failują (C2)', () => __awaiter(void 0, void 0, void 0, function* () {
113
+ rpcConn.brpop.mockResolvedValue(null);
114
+ mockConn.del.mockRejectedValue(new Error('Connection lost'));
115
+ mockConn.expire.mockRejectedValue(new Error('Connection lost'));
116
+ // Powinien rzucić TYLKO RPC timeout, nie błąd z DEL/EXPIRE
117
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 1000)).rejects.toThrow('RPC timeout');
118
+ }));
119
+ it('nie powinien zawierać correlationId w error message (M2)', () => __awaiter(void 0, void 0, void 0, function* () {
120
+ rpcConn.brpop.mockResolvedValue(null);
121
+ try {
122
+ yield handler.rpcCall('TestCommand', Buffer.from('data'), 1000);
123
+ }
124
+ catch (error) {
125
+ const message = error.message;
126
+ expect(message).not.toContain('correlationId');
127
+ }
128
+ }));
129
+ it('powinien rzucić błąd przy timeout 0 (M1)', () => __awaiter(void 0, void 0, void 0, function* () {
130
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), 0)).rejects.toThrow('Nieprawidłowy timeout RPC: 0ms');
131
+ }));
132
+ it('powinien rzucić błąd przy negatywnym timeout (M1)', () => __awaiter(void 0, void 0, void 0, function* () {
133
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), -100)).rejects.toThrow('Nieprawidłowy timeout RPC: -100ms');
134
+ }));
135
+ it('powinien rzucić błąd przy Infinity timeout (M1)', () => __awaiter(void 0, void 0, void 0, function* () {
136
+ yield expect(handler.rpcCall('TestCommand', Buffer.from('data'), Infinity)).rejects.toThrow('Nieprawidłowy timeout RPC: Infinityms');
137
+ }));
138
+ it('powinien użyć minimum 1 sekundy dla BRPOP timeout', () => __awaiter(void 0, void 0, void 0, function* () {
139
+ const responseData = Buffer.from(JSON.stringify({ result: 'ok' }));
140
+ rpcConn.brpop.mockResolvedValue(['rpc:res:test', redis_codec_1.RedisCodec.encode(responseData)]);
141
+ yield handler.rpcCall('TestCommand', Buffer.from('data'), 100); // 100ms < 1s
142
+ // BRPOP powinien mieć timeout = 1 (minimalna wartość)
143
+ expect(rpcConn.brpop).toHaveBeenCalledWith(expect.stringContaining('rpc:res:'), 1);
144
+ }));
145
+ });
146
+ describe('rpcRespond()', () => {
147
+ it('powinien wysłać odpowiedź przez pipeline LPUSH + EXPIRE', () => __awaiter(void 0, void 0, void 0, function* () {
148
+ const responseData = Buffer.from('response');
149
+ yield handler.rpcRespond('rpc:res:test-id', responseData, 60);
150
+ const pipeline = mockConn.pipeline();
151
+ expect(mockConn.pipeline).toHaveBeenCalled();
152
+ expect(pipeline.lpush).toHaveBeenCalledWith('rpc:res:test-id', redis_codec_1.RedisCodec.encode(responseData));
153
+ expect(pipeline.expire).toHaveBeenCalledWith('rpc:res:test-id', 60);
154
+ }));
155
+ });
156
+ });
157
+ //# sourceMappingURL=rpc-handler.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-handler.spec.js","sourceRoot":"","sources":["../../../src/command-bus/transport/rpc-handler.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import type { ILogger } from '../../shared/types';
2
+ import type { ISerializer } from '../serialization/serializer.interface';
3
+ import type { IStreamConsumer, ConsumerHandler } from './transport.interface';
4
+ import type RedisConnectionPool from '../../shared/redis/connection-pool';
5
+ import type { ICommandInterceptor } from '../interceptors';
6
+ import type { RpcResponder } from './message-processor';
7
+ /**
8
+ * Konfiguracja StreamConsumer
9
+ */
10
+ export interface StreamConsumerOptions {
11
+ pool: RedisConnectionPool;
12
+ serializer: ISerializer;
13
+ logger: ILogger;
14
+ consumerId: string;
15
+ batchSize: number;
16
+ concurrency: number;
17
+ maxRetained: number;
18
+ rpcRespond: RpcResponder;
19
+ interceptor?: ICommandInterceptor;
20
+ /** Próg czasu (ms) po którym wpis w processing Map jest uznawany za stale (domyślnie 300_000 = 5min) */
21
+ staleThreshold?: number;
22
+ /** Minimalny interwał (ms) między sweepami stale wpisów (domyślnie 10_000 = 10s) */
23
+ sweepInterval?: number;
24
+ }
25
+ /**
26
+ * Koordynator konsumenta strumienia Redis — komponuje MessageProcessor i ConsumerLoop
27
+ *
28
+ * Odpowiedzialności:
29
+ * - Zarządzanie cyklem życia: tworzenie połączeń, consumer groups, uruchamianie loops
30
+ * - Deduplicacja (processing Map z TTL sweep) (H1)
31
+ * - Koordynacja komponentów: MessageProcessor i ConsumerLoop
32
+ *
33
+ * NIE odpowiada za:
34
+ * - Przetwarzanie wiadomości (MessageProcessor)
35
+ * - Consumer loop z concurrency limiter (ConsumerLoop)
36
+ */
37
+ export declare class StreamConsumer implements IStreamConsumer {
38
+ private readonly pool;
39
+ private readonly logger;
40
+ private readonly consumerId;
41
+ private readonly batchSize;
42
+ private readonly concurrency;
43
+ /** H1: Próg czasu (ms) po którym wpis w processing Map jest uznawany za stale */
44
+ private readonly staleThreshold;
45
+ /** Timestamp ostatniego sweep — throttle co sweepInterval */
46
+ private lastSweepTime;
47
+ /** Minimalny interwał między sweep (ms) */
48
+ private readonly sweepInterval;
49
+ /** Procesor wiadomości — parsuje, waliduje, przetwarza */
50
+ private readonly messageProcessor;
51
+ /** Instancje consumer loops — do propagacji flagi running */
52
+ private readonly loops;
53
+ /** Dedykowane połączenia konsumentów (XREADGROUP BLOCK) */
54
+ private readonly consumerConnections;
55
+ /** Promises consumer loops — do graceful shutdown */
56
+ private readonly consumerLoopPromises;
57
+ /** H1: Wiadomości aktualnie przetwarzane — Map<messageId, timestamp> z TTL sweep */
58
+ private readonly processing;
59
+ /** Flaga zatrzymania — propaguje do wszystkich consumer loops */
60
+ private _running;
61
+ get running(): boolean;
62
+ set running(value: boolean);
63
+ /** Zwraca liczbę aktywnych konsumentów (do logów) */
64
+ get consumerCount(): number;
65
+ /**
66
+ * Zamyka dedykowane połączenia konsumentów (przerywa XREADGROUP BLOCK)
67
+ */
68
+ closeConnections(): void;
69
+ /**
70
+ * Czeka na zakończenie consumer loops
71
+ */
72
+ awaitLoops(): Promise<void>;
73
+ constructor(options: StreamConsumerOptions);
74
+ /**
75
+ * Rejestruje konsumenta dla strumienia z consumer group
76
+ * Tworzy dedykowane połączenie (XREADGROUP BLOCK blokuje socket)
77
+ */
78
+ consume(streamName: string, groupName: string, handler: ConsumerHandler): Promise<void>;
79
+ /**
80
+ * Przetwarza pojedynczą wiadomość ze strumienia
81
+ * Deduplicacja + delegacja do MessageProcessor
82
+ *
83
+ * Wywoływane zarówno przez ConsumerLoop (nowe wiadomości) jak i PendingRecovery (XCLAIM)
84
+ */
85
+ processMessage(streamName: string, groupName: string, messageId: string, fields: string[], handler: ConsumerHandler): Promise<void>;
86
+ /**
87
+ * H1: Usuwa stale wpisy z processing Map — zapobiega permanentnej blokadzie recovery
88
+ * Wpis uznawany za stale gdy trwa dłużej niż staleThreshold
89
+ */
90
+ private sweepStaleProcessing;
91
+ }
@@ -0,0 +1,182 @@
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.StreamConsumer = void 0;
13
+ const message_processor_1 = require("./message-processor");
14
+ const consumer_loop_1 = require("./consumer-loop");
15
+ const error_utils_1 = require("../../shared/utils/error-utils");
16
+ /**
17
+ * Koordynator konsumenta strumienia Redis — komponuje MessageProcessor i ConsumerLoop
18
+ *
19
+ * Odpowiedzialności:
20
+ * - Zarządzanie cyklem życia: tworzenie połączeń, consumer groups, uruchamianie loops
21
+ * - Deduplicacja (processing Map z TTL sweep) (H1)
22
+ * - Koordynacja komponentów: MessageProcessor i ConsumerLoop
23
+ *
24
+ * NIE odpowiada za:
25
+ * - Przetwarzanie wiadomości (MessageProcessor)
26
+ * - Consumer loop z concurrency limiter (ConsumerLoop)
27
+ */
28
+ class StreamConsumer {
29
+ get running() {
30
+ return this._running;
31
+ }
32
+ set running(value) {
33
+ this._running = value;
34
+ for (const loop of this.loops) {
35
+ loop.running = value;
36
+ }
37
+ }
38
+ /** Zwraca liczbę aktywnych konsumentów (do logów) */
39
+ get consumerCount() {
40
+ return this.consumerConnections.length;
41
+ }
42
+ /**
43
+ * Zamyka dedykowane połączenia konsumentów (przerywa XREADGROUP BLOCK)
44
+ */
45
+ closeConnections() {
46
+ for (const conn of this.consumerConnections) {
47
+ conn.disconnect();
48
+ }
49
+ this.consumerConnections.length = 0;
50
+ }
51
+ /**
52
+ * Czeka na zakończenie consumer loops
53
+ */
54
+ awaitLoops() {
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ if (this.consumerLoopPromises.length > 0) {
57
+ yield Promise.allSettled(this.consumerLoopPromises);
58
+ this.consumerLoopPromises.length = 0;
59
+ }
60
+ });
61
+ }
62
+ constructor(options) {
63
+ var _a, _b;
64
+ /** Timestamp ostatniego sweep — throttle co sweepInterval */
65
+ this.lastSweepTime = 0;
66
+ /** Instancje consumer loops — do propagacji flagi running */
67
+ this.loops = [];
68
+ /** Dedykowane połączenia konsumentów (XREADGROUP BLOCK) */
69
+ this.consumerConnections = [];
70
+ /** Promises consumer loops — do graceful shutdown */
71
+ this.consumerLoopPromises = [];
72
+ /** H1: Wiadomości aktualnie przetwarzane — Map<messageId, timestamp> z TTL sweep */
73
+ this.processing = new Map();
74
+ /** Flaga zatrzymania — propaguje do wszystkich consumer loops */
75
+ this._running = true;
76
+ this.pool = options.pool;
77
+ this.logger = options.logger;
78
+ this.consumerId = options.consumerId;
79
+ this.batchSize = options.batchSize;
80
+ this.concurrency = options.concurrency;
81
+ this.staleThreshold = (_a = options.staleThreshold) !== null && _a !== void 0 ? _a : 300000;
82
+ this.sweepInterval = (_b = options.sweepInterval) !== null && _b !== void 0 ? _b : 10000;
83
+ this.messageProcessor = new message_processor_1.MessageProcessor({
84
+ pool: options.pool,
85
+ serializer: options.serializer,
86
+ logger: options.logger,
87
+ batchSize: options.batchSize,
88
+ maxRetained: options.maxRetained,
89
+ rpcRespond: options.rpcRespond,
90
+ interceptor: options.interceptor,
91
+ });
92
+ }
93
+ /**
94
+ * Rejestruje konsumenta dla strumienia z consumer group
95
+ * Tworzy dedykowane połączenie (XREADGROUP BLOCK blokuje socket)
96
+ */
97
+ consume(streamName, groupName, handler) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ const conn = this.pool.createDedicated(streamName);
100
+ this.consumerConnections.push(conn);
101
+ // Utwórz consumer group (ignoruj jeśli już istnieje)
102
+ try {
103
+ yield conn.xgroup('CREATE', streamName, groupName, '0', 'MKSTREAM');
104
+ }
105
+ catch (error) {
106
+ const msg = (0, error_utils_1.getErrorMessage)(error);
107
+ if (!msg.includes('BUSYGROUP')) {
108
+ throw error;
109
+ }
110
+ }
111
+ // Utwórz consumer loop i uruchom w tle
112
+ const loop = new consumer_loop_1.ConsumerLoop({
113
+ consumerId: this.consumerId,
114
+ batchSize: this.batchSize,
115
+ concurrency: this.concurrency,
116
+ logger: this.logger,
117
+ });
118
+ this.loops.push(loop);
119
+ const loopPromise = loop.run(conn, streamName, groupName, (messageId, fields) => this.processMessage(streamName, groupName, messageId, fields, handler));
120
+ this.consumerLoopPromises.push(loopPromise);
121
+ this.logger.debug('Konsument zarejestrowany', {
122
+ streamName,
123
+ groupName,
124
+ consumerId: this.consumerId,
125
+ timestamp: new Date().toISOString(),
126
+ });
127
+ });
128
+ }
129
+ /**
130
+ * Przetwarza pojedynczą wiadomość ze strumienia
131
+ * Deduplicacja + delegacja do MessageProcessor
132
+ *
133
+ * Wywoływane zarówno przez ConsumerLoop (nowe wiadomości) jak i PendingRecovery (XCLAIM)
134
+ */
135
+ processMessage(streamName, groupName, messageId, fields, handler) {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ // H1: Throttled sweep stale wpisów — co sweepInterval zamiast na każdą wiadomość
138
+ const now = Date.now();
139
+ if (now - this.lastSweepTime > this.sweepInterval) {
140
+ this.sweepStaleProcessing();
141
+ this.lastSweepTime = now;
142
+ }
143
+ if (this.processing.has(messageId)) {
144
+ return;
145
+ }
146
+ this.processing.set(messageId, Date.now());
147
+ try {
148
+ yield this.messageProcessor.process(streamName, groupName, messageId, fields, handler);
149
+ }
150
+ catch (error) {
151
+ this.logger.error('Błąd przetwarzania wiadomości', {
152
+ streamName,
153
+ messageId,
154
+ error: (0, error_utils_1.getErrorMessage)(error),
155
+ timestamp: new Date().toISOString(),
156
+ });
157
+ }
158
+ finally {
159
+ this.processing.delete(messageId);
160
+ }
161
+ });
162
+ }
163
+ /**
164
+ * H1: Usuwa stale wpisy z processing Map — zapobiega permanentnej blokadzie recovery
165
+ * Wpis uznawany za stale gdy trwa dłużej niż staleThreshold
166
+ */
167
+ sweepStaleProcessing() {
168
+ const now = Date.now();
169
+ for (const [id, timestamp] of this.processing) {
170
+ if (now - timestamp > this.staleThreshold) {
171
+ this.processing.delete(id);
172
+ this.logger.warn('Usunięto stale wpis z processing Map', {
173
+ messageId: id,
174
+ age: now - timestamp,
175
+ threshold: this.staleThreshold,
176
+ });
177
+ }
178
+ }
179
+ }
180
+ }
181
+ exports.StreamConsumer = StreamConsumer;
182
+ //# sourceMappingURL=stream-consumer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-consumer.js","sourceRoot":"","sources":["../../../src/command-bus/transport/stream-consumer.ts"],"names":[],"mappings":"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"}