@zdavison/matador 4.0.0 → 4.0.2
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/core/fanout.d.ts +11 -0
- package/dist/core/fanout.d.ts.map +1 -1
- package/dist/core/fanout.js +103 -14
- package/dist/core/fanout.test.js +377 -5
- package/dist/core/matador.d.ts.map +1 -1
- package/dist/core/matador.js +1 -0
- package/dist/core/matador.test.js +1 -1
- package/dist/index.cjs +161 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/topology/builder.d.ts +4 -2
- package/dist/topology/builder.d.ts.map +1 -1
- package/dist/topology/builder.js +2 -0
- package/dist/topology/builder.test.js +9 -0
- package/dist/topology/index.d.ts +1 -1
- package/dist/topology/index.d.ts.map +1 -1
- package/dist/topology/types.d.ts +18 -6
- package/dist/topology/types.d.ts.map +1 -1
- package/dist/transport/multi/multi-transport.d.ts +6 -0
- package/dist/transport/multi/multi-transport.d.ts.map +1 -1
- package/dist/transport/multi/multi-transport.js +17 -0
- package/dist/transport/rabbitmq/rabbitmq-transport-reconnection.test.js +45 -6
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +6 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.js +52 -13
- package/dist/transport/transport.d.ts +6 -0
- package/dist/transport/transport.d.ts.map +1 -1
- package/dist/types/event.d.ts +17 -0
- package/dist/types/event.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core/fanout.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export interface FanoutConfig {
|
|
|
12
12
|
readonly hooks: SafeHooks;
|
|
13
13
|
readonly topology: Topology;
|
|
14
14
|
readonly defaultQueue: string;
|
|
15
|
+
readonly maxRetryBufferSize?: number | undefined;
|
|
15
16
|
}
|
|
16
17
|
/**
|
|
17
18
|
* Result of sending an event.
|
|
@@ -46,7 +47,11 @@ export declare class FanoutEngine {
|
|
|
46
47
|
private readonly topology;
|
|
47
48
|
private readonly defaultQueue;
|
|
48
49
|
private enqueuingCount;
|
|
50
|
+
private readonly retryBuffer;
|
|
51
|
+
private readonly maxRetryBufferSize;
|
|
52
|
+
private readonly disposeOnConnected;
|
|
49
53
|
constructor(config: FanoutConfig);
|
|
54
|
+
dispose(): void;
|
|
50
55
|
/**
|
|
51
56
|
* Current count of events being enqueued.
|
|
52
57
|
*/
|
|
@@ -55,6 +60,12 @@ export declare class FanoutEngine {
|
|
|
55
60
|
* Sends an event to all registered subscribers.
|
|
56
61
|
*/
|
|
57
62
|
send<T>(eventClass: EventClass<T>, event: Event<T>, options?: EventOptions): Promise<SendResult>;
|
|
63
|
+
/**
|
|
64
|
+
* Flushes the retry buffer
|
|
65
|
+
*
|
|
66
|
+
* This is called when the transport reconnects, and is used to retry any messages that were buffered while the transport was disconnected
|
|
67
|
+
*/
|
|
68
|
+
private flushRetryBuffer;
|
|
58
69
|
private isSubscriberEnabled;
|
|
59
70
|
}
|
|
60
71
|
//# sourceMappingURL=fanout.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../../src/core/fanout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"fanout.d.ts","sourceRoot":"","sources":["../../src/core/fanout.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAGV,KAAK,EACL,UAAU,EACV,YAAY,EACb,MAAM,mBAAmB,CAAC;AAa3B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClD;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,CAAC;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;;;;;;GAQG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;IAClD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA2B;gBAElD,MAAM,EAAE,YAAY;IAehC,OAAO,IAAI,IAAI;IAKf;;OAEG;IACH,IAAI,wBAAwB,IAAI,MAAM,CAErC;IAED;;OAEG;IACG,IAAI,CAAC,CAAC,EACV,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,UAAU,CAAC;IAyHtB;;;;OAIG;YACW,gBAAgB;YAsDhB,mBAAmB;CAelC"}
|
package/dist/core/fanout.js
CHANGED
|
@@ -17,12 +17,25 @@ export class FanoutEngine {
|
|
|
17
17
|
topology;
|
|
18
18
|
defaultQueue;
|
|
19
19
|
enqueuingCount = 0;
|
|
20
|
+
retryBuffer = [];
|
|
21
|
+
maxRetryBufferSize;
|
|
22
|
+
disposeOnConnected;
|
|
20
23
|
constructor(config) {
|
|
21
24
|
this.transport = config.transport;
|
|
22
25
|
this.schema = config.schema;
|
|
23
26
|
this.hooks = config.hooks;
|
|
24
27
|
this.topology = config.topology;
|
|
25
28
|
this.defaultQueue = config.defaultQueue;
|
|
29
|
+
this.maxRetryBufferSize = config.maxRetryBufferSize ?? 5000;
|
|
30
|
+
// If the transport supports it, add a callback to flush the retry buffer when the transport reconnects
|
|
31
|
+
// The returned value is a function to unsubscribe from the callback
|
|
32
|
+
this.disposeOnConnected = this.transport.onConnected?.(() => {
|
|
33
|
+
void this.flushRetryBuffer();
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
dispose() {
|
|
37
|
+
// Unsubscribe from the callback (that flushes the retry buffer when the transport reconnects)
|
|
38
|
+
this.disposeOnConnected?.();
|
|
26
39
|
}
|
|
27
40
|
/**
|
|
28
41
|
* Current count of events being enqueued.
|
|
@@ -68,11 +81,10 @@ export class FanoutEngine {
|
|
|
68
81
|
delayMs: options.delayMs,
|
|
69
82
|
});
|
|
70
83
|
// Send to transport
|
|
84
|
+
const sendOptions = options.delayMs !== undefined ? { delay: options.delayMs } : undefined;
|
|
71
85
|
this.enqueuingCount++;
|
|
72
86
|
try {
|
|
73
|
-
const usedTransport = await this.transport.send(qualifiedQueue, envelope,
|
|
74
|
-
? { delay: options.delayMs }
|
|
75
|
-
: undefined);
|
|
87
|
+
const usedTransport = await this.transport.send(qualifiedQueue, envelope, sendOptions);
|
|
76
88
|
sent++;
|
|
77
89
|
await this.hooks.onEnqueueSuccess({
|
|
78
90
|
envelope,
|
|
@@ -82,17 +94,46 @@ export class FanoutEngine {
|
|
|
82
94
|
}
|
|
83
95
|
catch (error) {
|
|
84
96
|
const cause = error instanceof Error ? error : new Error(String(error));
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
97
|
+
const shouldBuffer = options.buffer !== false;
|
|
98
|
+
if (shouldBuffer && this.retryBuffer.length < this.maxRetryBufferSize) {
|
|
99
|
+
this.retryBuffer.push({
|
|
100
|
+
queue: qualifiedQueue,
|
|
101
|
+
envelope,
|
|
102
|
+
sendOptions,
|
|
103
|
+
subscriberName: subscriber.name,
|
|
104
|
+
});
|
|
105
|
+
this.hooks.logger.warn(`[Matador] 🟡 Message for '${subscriber.name}' buffered for retry on reconnect (buffer: ${this.retryBuffer.length}/${this.maxRetryBufferSize}).`);
|
|
106
|
+
if (options.throwOnBufferedFailure) {
|
|
107
|
+
const err = new TransportSendError(qualifiedQueue, cause);
|
|
108
|
+
// By adding the error, the main Send in Matador will throw
|
|
109
|
+
errors.push({
|
|
110
|
+
subscriberName: subscriber.name,
|
|
111
|
+
queue: qualifiedQueue,
|
|
112
|
+
error: err,
|
|
113
|
+
});
|
|
114
|
+
await this.hooks.onEnqueueError({
|
|
115
|
+
envelope,
|
|
116
|
+
error: err,
|
|
117
|
+
transport: this.transport.name,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
if (shouldBuffer) {
|
|
123
|
+
this.hooks.logger.error(`[Matador] 🔴 Retry buffer full (${this.maxRetryBufferSize}). Message for '${subscriber.name}' dropped and will not be retried.`);
|
|
124
|
+
}
|
|
125
|
+
const err = new TransportSendError(qualifiedQueue, cause);
|
|
126
|
+
errors.push({
|
|
127
|
+
subscriberName: subscriber.name,
|
|
128
|
+
queue: qualifiedQueue,
|
|
129
|
+
error: err,
|
|
130
|
+
});
|
|
131
|
+
await this.hooks.onEnqueueError({
|
|
132
|
+
envelope,
|
|
133
|
+
error: err,
|
|
134
|
+
transport: this.transport.name,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
96
137
|
}
|
|
97
138
|
finally {
|
|
98
139
|
this.enqueuingCount--;
|
|
@@ -105,6 +146,54 @@ export class FanoutEngine {
|
|
|
105
146
|
errors,
|
|
106
147
|
};
|
|
107
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Flushes the retry buffer
|
|
151
|
+
*
|
|
152
|
+
* This is called when the transport reconnects, and is used to retry any messages that were buffered while the transport was disconnected
|
|
153
|
+
*/
|
|
154
|
+
async flushRetryBuffer() {
|
|
155
|
+
if (this.retryBuffer.length === 0)
|
|
156
|
+
return;
|
|
157
|
+
this.hooks.logger.info(`[Matador] ⏳ Flushing ${this.retryBuffer.length} buffered message(s)...`);
|
|
158
|
+
// Drain the buffer atomically so concurrent flush calls don't double-send.
|
|
159
|
+
const toFlush = this.retryBuffer.splice(0);
|
|
160
|
+
for (const item of toFlush) {
|
|
161
|
+
this.enqueuingCount++;
|
|
162
|
+
try {
|
|
163
|
+
const usedTransport = await this.transport.send(item.queue, item.envelope, item.sendOptions);
|
|
164
|
+
await this.hooks.onEnqueueSuccess({
|
|
165
|
+
envelope: item.envelope,
|
|
166
|
+
queue: item.queue,
|
|
167
|
+
transport: usedTransport,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
// Re-buffer on failure; it will be retried on the next reconnect.
|
|
172
|
+
if (this.retryBuffer.length < this.maxRetryBufferSize) {
|
|
173
|
+
this.retryBuffer.push(item);
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
const cause = error instanceof Error ? error : new Error(String(error));
|
|
177
|
+
const err = new TransportSendError(item.queue, cause);
|
|
178
|
+
await this.hooks.onEnqueueError({
|
|
179
|
+
envelope: item.envelope,
|
|
180
|
+
error: err,
|
|
181
|
+
transport: this.transport.name,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
this.enqueuingCount--;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const remaining = this.retryBuffer.length;
|
|
190
|
+
if (remaining > 0) {
|
|
191
|
+
this.hooks.logger.warn(`[Matador] 🟡 ${remaining} buffered message(s) could not be flushed; will retry on next reconnect.`);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
this.hooks.logger.info('[Matador] 🟢 All buffered messages flushed successfully.');
|
|
195
|
+
}
|
|
196
|
+
}
|
|
108
197
|
async isSubscriberEnabled(subscriber) {
|
|
109
198
|
if (!subscriber.enabled) {
|
|
110
199
|
return true;
|
package/dist/core/fanout.test.js
CHANGED
|
@@ -3,6 +3,7 @@ import { TransportSendError } from '../errors/index.js';
|
|
|
3
3
|
import { SafeHooks } from '../hooks/index.js';
|
|
4
4
|
import { SchemaRegistry } from '../schema/index.js';
|
|
5
5
|
import { TopologyBuilder } from '../topology/index.js';
|
|
6
|
+
import { MultiTransport } from '../transport/index.js';
|
|
6
7
|
import { MatadorEvent, createSubscriber, createSubscriberStub, } from '../types/index.js';
|
|
7
8
|
import { FanoutEngine } from './fanout.js';
|
|
8
9
|
class UserCreatedEvent extends MatadorEvent {
|
|
@@ -514,7 +515,7 @@ describe('FanoutEngine', () => {
|
|
|
514
515
|
});
|
|
515
516
|
});
|
|
516
517
|
describe('error handling', () => {
|
|
517
|
-
it('should capture error when transport.send fails', async () => {
|
|
518
|
+
it('should capture error when transport.send fails and buffer is disabled', async () => {
|
|
518
519
|
const sendError = new Error('Network timeout');
|
|
519
520
|
const failingTransport = {
|
|
520
521
|
...transport,
|
|
@@ -539,7 +540,7 @@ describe('FanoutEngine', () => {
|
|
|
539
540
|
userId: '123',
|
|
540
541
|
email: 'test@example.com',
|
|
541
542
|
});
|
|
542
|
-
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event);
|
|
543
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event, { buffer: false });
|
|
543
544
|
expect(result.subscribersSent).toBe(0);
|
|
544
545
|
expect(result.subscribersSkipped).toBe(0);
|
|
545
546
|
expect(result.errors).toHaveLength(1);
|
|
@@ -581,7 +582,7 @@ describe('FanoutEngine', () => {
|
|
|
581
582
|
userId: '123',
|
|
582
583
|
email: 'test@example.com',
|
|
583
584
|
});
|
|
584
|
-
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event);
|
|
585
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event, { buffer: false });
|
|
585
586
|
expect(result.subscribersSent).toBe(1);
|
|
586
587
|
expect(result.subscribersSkipped).toBe(0);
|
|
587
588
|
expect(result.errors).toHaveLength(1);
|
|
@@ -611,7 +612,7 @@ describe('FanoutEngine', () => {
|
|
|
611
612
|
userId: '123',
|
|
612
613
|
email: 'test@example.com',
|
|
613
614
|
});
|
|
614
|
-
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event);
|
|
615
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event, { buffer: false });
|
|
615
616
|
expect(result.errors).toHaveLength(1);
|
|
616
617
|
expect(result.errors[0]?.error).toBeInstanceOf(TransportSendError);
|
|
617
618
|
expect(result.errors[0]?.error.message).toContain('matador.test.events');
|
|
@@ -867,7 +868,9 @@ describe('FanoutEngine', () => {
|
|
|
867
868
|
userId: '123',
|
|
868
869
|
email: 'test@example.com',
|
|
869
870
|
});
|
|
870
|
-
await fanoutWithHooks.send(UserCreatedEvent, event
|
|
871
|
+
await fanoutWithHooks.send(UserCreatedEvent, event, {
|
|
872
|
+
throwOnBufferedFailure: true,
|
|
873
|
+
});
|
|
871
874
|
expect(onEnqueueError).toHaveBeenCalledTimes(1);
|
|
872
875
|
expect(onEnqueueError).toHaveBeenCalledWith({
|
|
873
876
|
envelope: expect.any(Object),
|
|
@@ -1069,4 +1072,373 @@ describe('FanoutEngine', () => {
|
|
|
1069
1072
|
expect(envelope.docket.importance).toBe('should-investigate');
|
|
1070
1073
|
});
|
|
1071
1074
|
});
|
|
1075
|
+
describe('retry buffering', () => {
|
|
1076
|
+
it('should buffer a failed send and not return it as an error', async () => {
|
|
1077
|
+
const subscriber = createSubscriber({
|
|
1078
|
+
name: 'handle-user',
|
|
1079
|
+
description: 'Handles user events',
|
|
1080
|
+
callback: async () => { },
|
|
1081
|
+
});
|
|
1082
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1083
|
+
const failingTransport = {
|
|
1084
|
+
...transport,
|
|
1085
|
+
send: mock(async () => {
|
|
1086
|
+
throw new Error('Connection lost');
|
|
1087
|
+
}),
|
|
1088
|
+
};
|
|
1089
|
+
const fanoutWithFailingTransport = new FanoutEngine({
|
|
1090
|
+
transport: failingTransport,
|
|
1091
|
+
schema,
|
|
1092
|
+
hooks,
|
|
1093
|
+
topology: testTopology,
|
|
1094
|
+
defaultQueue: 'events',
|
|
1095
|
+
});
|
|
1096
|
+
const event = new UserCreatedEvent({
|
|
1097
|
+
userId: '123',
|
|
1098
|
+
email: 'test@example.com',
|
|
1099
|
+
});
|
|
1100
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event);
|
|
1101
|
+
expect(result.errors).toHaveLength(0);
|
|
1102
|
+
expect(result.subscribersSent).toBe(0);
|
|
1103
|
+
});
|
|
1104
|
+
it('should buffer stub failures too', async () => {
|
|
1105
|
+
const stub = createSubscriberStub({ name: 'remote-service' });
|
|
1106
|
+
schema.register(UserCreatedEvent, [stub]);
|
|
1107
|
+
const failingTransport = {
|
|
1108
|
+
...transport,
|
|
1109
|
+
send: mock(async () => {
|
|
1110
|
+
throw new Error('Connection lost');
|
|
1111
|
+
}),
|
|
1112
|
+
};
|
|
1113
|
+
const fanoutWithFailingTransport = new FanoutEngine({
|
|
1114
|
+
transport: failingTransport,
|
|
1115
|
+
schema,
|
|
1116
|
+
hooks,
|
|
1117
|
+
topology: testTopology,
|
|
1118
|
+
defaultQueue: 'events',
|
|
1119
|
+
});
|
|
1120
|
+
const event = new UserCreatedEvent({
|
|
1121
|
+
userId: '123',
|
|
1122
|
+
email: 'test@example.com',
|
|
1123
|
+
});
|
|
1124
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event);
|
|
1125
|
+
expect(result.errors).toHaveLength(0);
|
|
1126
|
+
expect(result.subscribersSent).toBe(0);
|
|
1127
|
+
});
|
|
1128
|
+
it('should flush buffered messages when onConnected fires', async () => {
|
|
1129
|
+
let connectedCallback;
|
|
1130
|
+
const failThenSucceed = mock(async () => {
|
|
1131
|
+
throw new Error('Connection lost');
|
|
1132
|
+
});
|
|
1133
|
+
const transportWithReconnect = {
|
|
1134
|
+
...transport,
|
|
1135
|
+
send: failThenSucceed,
|
|
1136
|
+
onConnected: (cb) => {
|
|
1137
|
+
connectedCallback = cb;
|
|
1138
|
+
return () => { };
|
|
1139
|
+
},
|
|
1140
|
+
};
|
|
1141
|
+
const fanoutWithReconnect = new FanoutEngine({
|
|
1142
|
+
transport: transportWithReconnect,
|
|
1143
|
+
schema,
|
|
1144
|
+
hooks,
|
|
1145
|
+
topology: testTopology,
|
|
1146
|
+
defaultQueue: 'events',
|
|
1147
|
+
});
|
|
1148
|
+
const subscriber = createSubscriber({
|
|
1149
|
+
name: 'handle-user',
|
|
1150
|
+
description: 'Handles user events',
|
|
1151
|
+
callback: async () => { },
|
|
1152
|
+
});
|
|
1153
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1154
|
+
const event = new UserCreatedEvent({
|
|
1155
|
+
userId: '123',
|
|
1156
|
+
email: 'test@example.com',
|
|
1157
|
+
});
|
|
1158
|
+
// First send — transport fails, message should be buffered
|
|
1159
|
+
await fanoutWithReconnect.send(UserCreatedEvent, event);
|
|
1160
|
+
expect(failThenSucceed).toHaveBeenCalledTimes(1);
|
|
1161
|
+
// Simulate reconnect — now send succeeds
|
|
1162
|
+
transportWithReconnect.send.mockImplementation(async () => 'mock');
|
|
1163
|
+
expect(connectedCallback).toBeDefined();
|
|
1164
|
+
connectedCallback?.();
|
|
1165
|
+
// Give the async flush a chance to run
|
|
1166
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1167
|
+
expect(transportWithReconnect.send).toHaveBeenCalledTimes(2);
|
|
1168
|
+
});
|
|
1169
|
+
it('should re-buffer on flush failure and retry on next reconnect', async () => {
|
|
1170
|
+
let connectedCallback;
|
|
1171
|
+
const transportWithReconnect = {
|
|
1172
|
+
...transport,
|
|
1173
|
+
send: mock(async () => {
|
|
1174
|
+
throw new Error('Still down');
|
|
1175
|
+
}),
|
|
1176
|
+
onConnected: (cb) => {
|
|
1177
|
+
connectedCallback = cb;
|
|
1178
|
+
return () => { };
|
|
1179
|
+
},
|
|
1180
|
+
};
|
|
1181
|
+
const fanoutWithReconnect = new FanoutEngine({
|
|
1182
|
+
transport: transportWithReconnect,
|
|
1183
|
+
schema,
|
|
1184
|
+
hooks,
|
|
1185
|
+
topology: testTopology,
|
|
1186
|
+
defaultQueue: 'events',
|
|
1187
|
+
});
|
|
1188
|
+
const subscriber = createSubscriber({
|
|
1189
|
+
name: 'handle-user',
|
|
1190
|
+
description: 'Handles user events',
|
|
1191
|
+
callback: async () => { },
|
|
1192
|
+
});
|
|
1193
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1194
|
+
const event = new UserCreatedEvent({
|
|
1195
|
+
userId: '123',
|
|
1196
|
+
email: 'test@example.com',
|
|
1197
|
+
});
|
|
1198
|
+
await fanoutWithReconnect.send(UserCreatedEvent, event);
|
|
1199
|
+
expect(transportWithReconnect.send).toHaveBeenCalledTimes(1);
|
|
1200
|
+
// Simulate reconnect — flush fails, item should be re-buffered
|
|
1201
|
+
connectedCallback?.();
|
|
1202
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1203
|
+
// send was attempted again during the flush
|
|
1204
|
+
expect(transportWithReconnect.send).toHaveBeenCalledTimes(2);
|
|
1205
|
+
// Simulate a second reconnect — should retry again
|
|
1206
|
+
connectedCallback?.();
|
|
1207
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1208
|
+
expect(transportWithReconnect.send).toHaveBeenCalledTimes(3);
|
|
1209
|
+
});
|
|
1210
|
+
it('should not buffer when transport works fine', async () => {
|
|
1211
|
+
let connectedCallback;
|
|
1212
|
+
const successTransport = {
|
|
1213
|
+
...transport,
|
|
1214
|
+
onConnected: (cb) => {
|
|
1215
|
+
connectedCallback = cb;
|
|
1216
|
+
return () => { };
|
|
1217
|
+
},
|
|
1218
|
+
};
|
|
1219
|
+
const fanoutWithReconnect = new FanoutEngine({
|
|
1220
|
+
transport: successTransport,
|
|
1221
|
+
schema,
|
|
1222
|
+
hooks,
|
|
1223
|
+
topology: testTopology,
|
|
1224
|
+
defaultQueue: 'events',
|
|
1225
|
+
});
|
|
1226
|
+
const subscriber = createSubscriber({
|
|
1227
|
+
name: 'handle-user',
|
|
1228
|
+
description: 'Handles user events',
|
|
1229
|
+
callback: async () => { },
|
|
1230
|
+
});
|
|
1231
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1232
|
+
const event = new UserCreatedEvent({
|
|
1233
|
+
userId: '123',
|
|
1234
|
+
email: 'test@example.com',
|
|
1235
|
+
});
|
|
1236
|
+
const result = await fanoutWithReconnect.send(UserCreatedEvent, event);
|
|
1237
|
+
expect(result.subscribersSent).toBe(1);
|
|
1238
|
+
expect(result.errors).toHaveLength(0);
|
|
1239
|
+
// onConnected fires — nothing buffered so flush is a no-op
|
|
1240
|
+
connectedCallback?.();
|
|
1241
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1242
|
+
// Only one call total (the original send — not a spurious re-send)
|
|
1243
|
+
expect(successTransport.send).toHaveBeenCalledTimes(1);
|
|
1244
|
+
});
|
|
1245
|
+
it('should report error in result when buffer is false', async () => {
|
|
1246
|
+
const subscriber = createSubscriber({
|
|
1247
|
+
name: 'handle-user',
|
|
1248
|
+
description: 'Handles user events',
|
|
1249
|
+
callback: async () => { },
|
|
1250
|
+
});
|
|
1251
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1252
|
+
const failingTransport = {
|
|
1253
|
+
...transport,
|
|
1254
|
+
send: mock(async () => {
|
|
1255
|
+
throw new Error('Connection lost');
|
|
1256
|
+
}),
|
|
1257
|
+
};
|
|
1258
|
+
const fanoutWithFailingTransport = new FanoutEngine({
|
|
1259
|
+
transport: failingTransport,
|
|
1260
|
+
schema,
|
|
1261
|
+
hooks,
|
|
1262
|
+
topology: testTopology,
|
|
1263
|
+
defaultQueue: 'events',
|
|
1264
|
+
});
|
|
1265
|
+
const event = new UserCreatedEvent({
|
|
1266
|
+
userId: '123',
|
|
1267
|
+
email: 'test@example.com',
|
|
1268
|
+
});
|
|
1269
|
+
const result = await fanoutWithFailingTransport.send(UserCreatedEvent, event, { buffer: false });
|
|
1270
|
+
expect(result.errors).toHaveLength(1);
|
|
1271
|
+
expect(result.errors[0]?.subscriberName).toBe('handle-user');
|
|
1272
|
+
expect(result.errors[0]?.error).toBeInstanceOf(TransportSendError);
|
|
1273
|
+
});
|
|
1274
|
+
it('should both buffer and report error when reportBufferedFailure is true', async () => {
|
|
1275
|
+
let connectedCallback;
|
|
1276
|
+
const failingTransport = {
|
|
1277
|
+
...transport,
|
|
1278
|
+
send: mock(async () => {
|
|
1279
|
+
throw new Error('Connection lost');
|
|
1280
|
+
}),
|
|
1281
|
+
onConnected: (cb) => {
|
|
1282
|
+
connectedCallback = cb;
|
|
1283
|
+
return () => { };
|
|
1284
|
+
},
|
|
1285
|
+
};
|
|
1286
|
+
const fanoutWithReconnect = new FanoutEngine({
|
|
1287
|
+
transport: failingTransport,
|
|
1288
|
+
schema,
|
|
1289
|
+
hooks,
|
|
1290
|
+
topology: testTopology,
|
|
1291
|
+
defaultQueue: 'events',
|
|
1292
|
+
});
|
|
1293
|
+
const subscriber = createSubscriber({
|
|
1294
|
+
name: 'handle-user',
|
|
1295
|
+
description: 'Handles user events',
|
|
1296
|
+
callback: async () => { },
|
|
1297
|
+
});
|
|
1298
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1299
|
+
const event = new UserCreatedEvent({
|
|
1300
|
+
userId: '123',
|
|
1301
|
+
email: 'test@example.com',
|
|
1302
|
+
});
|
|
1303
|
+
const result = await fanoutWithReconnect.send(UserCreatedEvent, event, {
|
|
1304
|
+
throwOnBufferedFailure: true,
|
|
1305
|
+
});
|
|
1306
|
+
// Error is reported immediately
|
|
1307
|
+
expect(result.errors).toHaveLength(1);
|
|
1308
|
+
expect(result.errors[0]?.subscriberName).toBe('handle-user');
|
|
1309
|
+
// But it was also buffered — it should retry on reconnect
|
|
1310
|
+
failingTransport.send.mockImplementation(async () => 'mock');
|
|
1311
|
+
connectedCallback?.();
|
|
1312
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
1313
|
+
expect(failingTransport.send).toHaveBeenCalledTimes(2);
|
|
1314
|
+
});
|
|
1315
|
+
it('should unsubscribe the onConnected listener when dispose() is called', () => {
|
|
1316
|
+
const unsubscribe = mock(() => { });
|
|
1317
|
+
const transportWithOnConnected = {
|
|
1318
|
+
...transport,
|
|
1319
|
+
onConnected: mock((_cb) => unsubscribe),
|
|
1320
|
+
};
|
|
1321
|
+
const fanout = new FanoutEngine({
|
|
1322
|
+
transport: transportWithOnConnected,
|
|
1323
|
+
schema,
|
|
1324
|
+
hooks,
|
|
1325
|
+
topology: testTopology,
|
|
1326
|
+
defaultQueue: 'events',
|
|
1327
|
+
});
|
|
1328
|
+
expect(unsubscribe).not.toHaveBeenCalled();
|
|
1329
|
+
fanout.dispose();
|
|
1330
|
+
expect(unsubscribe).toHaveBeenCalledTimes(1);
|
|
1331
|
+
});
|
|
1332
|
+
it('should drop and report error when retry buffer is full', async () => {
|
|
1333
|
+
const subscriber = createSubscriber({
|
|
1334
|
+
name: 'handle-user',
|
|
1335
|
+
description: 'Handles user events',
|
|
1336
|
+
callback: async () => { },
|
|
1337
|
+
});
|
|
1338
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1339
|
+
const failingTransport = {
|
|
1340
|
+
...transport,
|
|
1341
|
+
send: mock(async () => {
|
|
1342
|
+
throw new Error('Connection lost');
|
|
1343
|
+
}),
|
|
1344
|
+
};
|
|
1345
|
+
const fanoutWithSmallBuffer = new FanoutEngine({
|
|
1346
|
+
transport: failingTransport,
|
|
1347
|
+
schema,
|
|
1348
|
+
hooks,
|
|
1349
|
+
topology: testTopology,
|
|
1350
|
+
defaultQueue: 'events',
|
|
1351
|
+
maxRetryBufferSize: 1,
|
|
1352
|
+
});
|
|
1353
|
+
const event = new UserCreatedEvent({
|
|
1354
|
+
userId: '123',
|
|
1355
|
+
email: 'test@example.com',
|
|
1356
|
+
});
|
|
1357
|
+
// First send fills the buffer
|
|
1358
|
+
const first = await fanoutWithSmallBuffer.send(UserCreatedEvent, event);
|
|
1359
|
+
expect(first.errors).toHaveLength(0);
|
|
1360
|
+
// Second send hits the full buffer — must report an error
|
|
1361
|
+
const second = await fanoutWithSmallBuffer.send(UserCreatedEvent, event);
|
|
1362
|
+
expect(second.errors).toHaveLength(1);
|
|
1363
|
+
expect(second.errors[0]?.error).toBeInstanceOf(TransportSendError);
|
|
1364
|
+
});
|
|
1365
|
+
it('should report buffer-full drop via onEnqueueError on initial send', async () => {
|
|
1366
|
+
const onEnqueueError = mock(async () => { });
|
|
1367
|
+
const hooksInstance = new SafeHooks({
|
|
1368
|
+
onEnqueueError,
|
|
1369
|
+
});
|
|
1370
|
+
const failingTransport = {
|
|
1371
|
+
...transport,
|
|
1372
|
+
send: mock(async () => {
|
|
1373
|
+
throw new Error('Connection lost');
|
|
1374
|
+
}),
|
|
1375
|
+
};
|
|
1376
|
+
const subscriber = createSubscriber({
|
|
1377
|
+
name: 'handle-user',
|
|
1378
|
+
description: 'Handles user events',
|
|
1379
|
+
callback: async () => { },
|
|
1380
|
+
});
|
|
1381
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1382
|
+
const fanoutWithSmallBuffer = new FanoutEngine({
|
|
1383
|
+
transport: failingTransport,
|
|
1384
|
+
schema,
|
|
1385
|
+
hooks: hooksInstance,
|
|
1386
|
+
topology: testTopology,
|
|
1387
|
+
defaultQueue: 'events',
|
|
1388
|
+
maxRetryBufferSize: 1,
|
|
1389
|
+
});
|
|
1390
|
+
const event = new UserCreatedEvent({
|
|
1391
|
+
userId: '123',
|
|
1392
|
+
email: 'test@example.com',
|
|
1393
|
+
});
|
|
1394
|
+
// First send fills the buffer — no error reported to caller or hook
|
|
1395
|
+
const first = await fanoutWithSmallBuffer.send(UserCreatedEvent, event);
|
|
1396
|
+
expect(first.errors).toHaveLength(0);
|
|
1397
|
+
expect(onEnqueueError).not.toHaveBeenCalled();
|
|
1398
|
+
// Second send finds the buffer full — onEnqueueError fires and error is returned
|
|
1399
|
+
const second = await fanoutWithSmallBuffer.send(UserCreatedEvent, event);
|
|
1400
|
+
expect(second.errors).toHaveLength(1);
|
|
1401
|
+
expect(onEnqueueError).toHaveBeenCalledTimes(1);
|
|
1402
|
+
});
|
|
1403
|
+
it('should not buffer when a fallback transport succeeds after the primary fails', async () => {
|
|
1404
|
+
const rabbitMock = {
|
|
1405
|
+
...transport,
|
|
1406
|
+
name: 'rabbitmq',
|
|
1407
|
+
send: mock(async () => {
|
|
1408
|
+
throw new Error('RabbitMQ down');
|
|
1409
|
+
}),
|
|
1410
|
+
};
|
|
1411
|
+
const localMock = {
|
|
1412
|
+
...transport,
|
|
1413
|
+
name: 'local',
|
|
1414
|
+
send: mock(async () => 'local'),
|
|
1415
|
+
};
|
|
1416
|
+
const multiTransport = new MultiTransport({
|
|
1417
|
+
transports: [rabbitMock, localMock],
|
|
1418
|
+
});
|
|
1419
|
+
const fanoutWithMulti = new FanoutEngine({
|
|
1420
|
+
transport: multiTransport,
|
|
1421
|
+
schema,
|
|
1422
|
+
hooks,
|
|
1423
|
+
topology: testTopology,
|
|
1424
|
+
defaultQueue: 'events',
|
|
1425
|
+
});
|
|
1426
|
+
const subscriber = createSubscriber({
|
|
1427
|
+
name: 'handle-user',
|
|
1428
|
+
description: 'Handles user events',
|
|
1429
|
+
callback: async () => { },
|
|
1430
|
+
});
|
|
1431
|
+
schema.register(UserCreatedEvent, [subscriber]);
|
|
1432
|
+
const event = new UserCreatedEvent({
|
|
1433
|
+
userId: '123',
|
|
1434
|
+
email: 'test@example.com',
|
|
1435
|
+
});
|
|
1436
|
+
const result = await fanoutWithMulti.send(UserCreatedEvent, event);
|
|
1437
|
+
expect(result.subscribersSent).toBe(1);
|
|
1438
|
+
expect(result.errors).toHaveLength(0);
|
|
1439
|
+
expect(rabbitMock.send).toHaveBeenCalledTimes(1);
|
|
1440
|
+
expect(localMock.send).toHaveBeenCalledTimes(1);
|
|
1441
|
+
expect(fanoutWithMulti.eventsBeingEnqueuedCount).toBe(0);
|
|
1442
|
+
});
|
|
1443
|
+
});
|
|
1072
1444
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"matador.d.ts","sourceRoot":"","sources":["../../src/core/matador.ts"],"names":[],"mappings":"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"}
|
package/dist/core/matador.js
CHANGED
|
@@ -317,7 +317,7 @@ describe('Matador', () => {
|
|
|
317
317
|
throw sendError;
|
|
318
318
|
});
|
|
319
319
|
const thrown = await matador
|
|
320
|
-
.send(new UserCreatedEvent({ userId: '123', email: 'test@example.com' }))
|
|
320
|
+
.send(new UserCreatedEvent({ userId: '123', email: 'test@example.com' }), { buffer: false })
|
|
321
321
|
.catch((e) => e);
|
|
322
322
|
expect(thrown).toBeInstanceOf(SomeSendError);
|
|
323
323
|
expect(thrown.eventKey).toBe(UserCreatedEvent.key);
|