@zdavison/matador 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/fanout.d.ts +51 -0
- package/dist/core/fanout.d.ts.map +1 -1
- package/dist/core/fanout.js +141 -28
- package/dist/core/fanout.test.js +533 -7
- package/dist/core/matador.d.ts +33 -0
- package/dist/core/matador.d.ts.map +1 -1
- package/dist/core/matador.js +9 -2
- package/dist/core/matador.test.js +336 -7
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +2 -2
- package/dist/errors/matador-errors.d.ts +10 -8
- package/dist/errors/matador-errors.d.ts.map +1 -1
- package/dist/errors/matador-errors.js +18 -14
- package/dist/index.cjs +326 -92
- 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 +2 -2
- package/dist/index.js.map +1 -1
- package/dist/pipeline/pipeline.d.ts +30 -2
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/pipeline.js +61 -9
- package/dist/pipeline/pipeline.test.js +123 -0
- package/dist/retry/index.d.ts +1 -1
- package/dist/retry/index.d.ts.map +1 -1
- package/dist/retry/policy.d.ts +25 -0
- package/dist/retry/policy.d.ts.map +1 -1
- package/dist/retry/standard-policy.d.ts +19 -1
- package/dist/retry/standard-policy.d.ts.map +1 -1
- package/dist/retry/standard-policy.js +39 -2
- package/dist/retry/standard-policy.test.js +65 -0
- package/dist/topology/builder.test.js +7 -0
- package/dist/topology/types.d.ts +14 -0
- package/dist/topology/types.d.ts.map +1 -1
- package/dist/transport/local/local-transport.d.ts +6 -0
- package/dist/transport/local/local-transport.d.ts.map +1 -1
- package/dist/transport/local/local-transport.js +35 -18
- package/dist/transport/local/local-transport.test.js +40 -4
- package/dist/transport/multi/multi-transport.d.ts.map +1 -1
- package/dist/transport/multi/multi-transport.js +3 -0
- package/dist/transport/multi/multi-transport.test.js +82 -0
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +1 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.js +34 -27
- package/dist/transport/rabbitmq/rabbitmq-transport.test.js +28 -0
- package/dist/transport/transport.d.ts +6 -0
- package/dist/transport/transport.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core/matador.js
CHANGED
|
@@ -66,6 +66,10 @@ export class Matador {
|
|
|
66
66
|
hooks: this.hooks,
|
|
67
67
|
topology: this.topology,
|
|
68
68
|
defaultQueue,
|
|
69
|
+
maxRetryBufferSize: config.maxRetryBufferSize,
|
|
70
|
+
maxRetryAttempts: config.maxRetryAttempts,
|
|
71
|
+
retryIntervalMs: config.retryIntervalMs,
|
|
72
|
+
maxConsecutiveFlushFailures: config.maxConsecutiveFlushFailures,
|
|
69
73
|
});
|
|
70
74
|
// Create shutdown manager
|
|
71
75
|
this.shutdownManager = new ShutdownManager(() => this.fanout.eventsBeingEnqueuedCount, () => this.unsubscribeAll(), () => this.transport.disconnect(), config.shutdownConfig);
|
|
@@ -137,6 +141,10 @@ export class Matador {
|
|
|
137
141
|
else {
|
|
138
142
|
this.hooks.logger.info('[Matador] 🟡 Worker not subscribing to any queues (consumeFrom is empty).');
|
|
139
143
|
}
|
|
144
|
+
// Mark as started
|
|
145
|
+
// Needed for the subscribe calls below, as we might start getting messages
|
|
146
|
+
// that could send events before the code here finishes subscribing to all the queues
|
|
147
|
+
this.started = true;
|
|
140
148
|
for (const queueName of this.consumeFrom) {
|
|
141
149
|
const qualifiedName = resolveTargetQueueName(this.topology, queueName);
|
|
142
150
|
const queueDef = findQueueDefinition(this.topology, queueName);
|
|
@@ -154,7 +162,6 @@ export class Matador {
|
|
|
154
162
|
: undefined);
|
|
155
163
|
this.subscriptions.push(subscription);
|
|
156
164
|
}
|
|
157
|
-
this.started = true;
|
|
158
165
|
}
|
|
159
166
|
async send(eventOrClass, dataOrOptions, maybeOptions) {
|
|
160
167
|
if (!this.started) {
|
|
@@ -247,7 +254,7 @@ export class Matador {
|
|
|
247
254
|
}
|
|
248
255
|
async unsubscribeAll() {
|
|
249
256
|
for (const subscription of this.subscriptions) {
|
|
250
|
-
await subscription.unsubscribe();
|
|
257
|
+
await (subscription.pauseForShutdown ?? subscription.unsubscribe)();
|
|
251
258
|
}
|
|
252
259
|
this.subscriptions.length = 0;
|
|
253
260
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, mock } from 'bun:test';
|
|
2
2
|
import { SomeSendError, TransportSendError } from '../errors/index.js';
|
|
3
3
|
import { TopologyBuilder } from '../topology/builder.js';
|
|
4
|
-
import { LocalTransport } from '../transport/
|
|
5
|
-
import { MatadorEvent, createSubscriber } from '../types/index.js';
|
|
4
|
+
import { LocalTransport, MultiTransport } from '../transport/index.js';
|
|
5
|
+
import { MatadorEvent, createDummyEnvelope, createSubscriber, } from '../types/index.js';
|
|
6
6
|
import { Matador } from './matador.js';
|
|
7
7
|
class UserCreatedEvent extends MatadorEvent {
|
|
8
8
|
data;
|
|
@@ -22,6 +22,24 @@ class OrderPlacedEvent extends MatadorEvent {
|
|
|
22
22
|
this.data = data;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
class StepOneEvent extends MatadorEvent {
|
|
26
|
+
data;
|
|
27
|
+
static key = 'step.one';
|
|
28
|
+
static description = 'First step of a chain';
|
|
29
|
+
constructor(data) {
|
|
30
|
+
super();
|
|
31
|
+
this.data = data;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
class StepTwoEvent extends MatadorEvent {
|
|
35
|
+
data;
|
|
36
|
+
static key = 'step.two';
|
|
37
|
+
static description = 'Follow-up step dispatched from within step one';
|
|
38
|
+
constructor(data) {
|
|
39
|
+
super();
|
|
40
|
+
this.data = data;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
25
43
|
describe('Matador', () => {
|
|
26
44
|
let transport;
|
|
27
45
|
let matador;
|
|
@@ -208,7 +226,12 @@ describe('Matador', () => {
|
|
|
208
226
|
const schema = {
|
|
209
227
|
[UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
|
|
210
228
|
};
|
|
211
|
-
matador = new Matador({
|
|
229
|
+
matador = new Matador({
|
|
230
|
+
transport,
|
|
231
|
+
topology,
|
|
232
|
+
schema,
|
|
233
|
+
consumeFrom: ['events'],
|
|
234
|
+
});
|
|
212
235
|
await matador.start();
|
|
213
236
|
const event = new UserCreatedEvent({
|
|
214
237
|
userId: '123',
|
|
@@ -231,7 +254,12 @@ describe('Matador', () => {
|
|
|
231
254
|
const schema = {
|
|
232
255
|
[UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
|
|
233
256
|
};
|
|
234
|
-
matador = new Matador({
|
|
257
|
+
matador = new Matador({
|
|
258
|
+
transport,
|
|
259
|
+
topology,
|
|
260
|
+
schema,
|
|
261
|
+
consumeFrom: ['events'],
|
|
262
|
+
});
|
|
235
263
|
await matador.start();
|
|
236
264
|
// Use the shorthand: send(EventClass, data)
|
|
237
265
|
const result = await matador.send(UserCreatedEvent, {
|
|
@@ -264,7 +292,12 @@ describe('Matador', () => {
|
|
|
264
292
|
const schema = {
|
|
265
293
|
[UserCreatedEvent.key]: [UserCreatedEvent, [sub1, sub2, sub3]],
|
|
266
294
|
};
|
|
267
|
-
matador = new Matador({
|
|
295
|
+
matador = new Matador({
|
|
296
|
+
transport,
|
|
297
|
+
topology,
|
|
298
|
+
schema,
|
|
299
|
+
consumeFrom: ['events'],
|
|
300
|
+
});
|
|
268
301
|
await matador.start();
|
|
269
302
|
const event = new UserCreatedEvent({
|
|
270
303
|
userId: '123',
|
|
@@ -286,7 +319,12 @@ describe('Matador', () => {
|
|
|
286
319
|
const schema = {
|
|
287
320
|
[UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
|
|
288
321
|
};
|
|
289
|
-
matador = new Matador({
|
|
322
|
+
matador = new Matador({
|
|
323
|
+
transport,
|
|
324
|
+
topology,
|
|
325
|
+
schema,
|
|
326
|
+
consumeFrom: ['events'],
|
|
327
|
+
});
|
|
290
328
|
await matador.start();
|
|
291
329
|
const event = new UserCreatedEvent({
|
|
292
330
|
userId: '123',
|
|
@@ -481,8 +519,19 @@ describe('Matador', () => {
|
|
|
481
519
|
const schema = {
|
|
482
520
|
[UserCreatedEvent.key]: [UserCreatedEvent, [subscriber]],
|
|
483
521
|
};
|
|
484
|
-
matador = new Matador({
|
|
522
|
+
matador = new Matador({
|
|
523
|
+
transport,
|
|
524
|
+
topology,
|
|
525
|
+
schema,
|
|
526
|
+
consumeFrom: ['events'],
|
|
527
|
+
});
|
|
485
528
|
await matador.start();
|
|
529
|
+
// stopReceiving() unsubscribes this instance's own handler. With a real
|
|
530
|
+
// broker, the queue would still exist independently (another replica,
|
|
531
|
+
// or this instance after restart, could pick the message up) — simulate
|
|
532
|
+
// that here with a subscription outside Matador's own lifecycle so
|
|
533
|
+
// LocalTransport still has somewhere to deliver to.
|
|
534
|
+
await transport.subscribe('matador.test.events', async () => { });
|
|
486
535
|
await matador.stopReceiving();
|
|
487
536
|
const event = new UserCreatedEvent({
|
|
488
537
|
userId: '123',
|
|
@@ -574,4 +623,284 @@ describe('Matador', () => {
|
|
|
574
623
|
expect(matador.isConnected()).toBe(true);
|
|
575
624
|
});
|
|
576
625
|
});
|
|
626
|
+
describe('start() race between subscribing and marking started', () => {
|
|
627
|
+
it('should allow send() from a subscriber callback fired while start() is still subscribing later queues', async () => {
|
|
628
|
+
const topology = TopologyBuilder.create()
|
|
629
|
+
.withNamespace('test')
|
|
630
|
+
.addQueue('events')
|
|
631
|
+
.addQueue('notifications')
|
|
632
|
+
.build();
|
|
633
|
+
let sendError;
|
|
634
|
+
const userSub = createSubscriber({
|
|
635
|
+
name: 'handle-user',
|
|
636
|
+
description: 'Handles user events',
|
|
637
|
+
callback: async (_envelope, context) => {
|
|
638
|
+
try {
|
|
639
|
+
await context.matador.send(OrderPlacedEvent, {
|
|
640
|
+
orderId: 'order-1',
|
|
641
|
+
amount: 100,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
catch (err) {
|
|
645
|
+
sendError = err;
|
|
646
|
+
}
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
const orderSub = createSubscriber({
|
|
650
|
+
name: 'handle-order',
|
|
651
|
+
description: 'Handles order events',
|
|
652
|
+
callback: async () => { },
|
|
653
|
+
});
|
|
654
|
+
const schema = {
|
|
655
|
+
[UserCreatedEvent.key]: [UserCreatedEvent, [userSub]],
|
|
656
|
+
[OrderPlacedEvent.key]: [OrderPlacedEvent, [orderSub]],
|
|
657
|
+
};
|
|
658
|
+
// Simulates a broker delivering a message on the first subscribed
|
|
659
|
+
// queue before subscribe() has resolved for a later queue - the
|
|
660
|
+
// exact window in which `started` used to still be false.
|
|
661
|
+
let capturedHandler;
|
|
662
|
+
let releaseSecondSubscribe;
|
|
663
|
+
const secondSubscribeGate = new Promise((resolve) => {
|
|
664
|
+
releaseSecondSubscribe = resolve;
|
|
665
|
+
});
|
|
666
|
+
const raceTransport = {
|
|
667
|
+
name: 'race-transport',
|
|
668
|
+
capabilities: {
|
|
669
|
+
deliveryModes: ['at-least-once'],
|
|
670
|
+
delayedMessages: false,
|
|
671
|
+
deadLetterRouting: 'native',
|
|
672
|
+
attemptTracking: true,
|
|
673
|
+
concurrencyModel: 'prefetch',
|
|
674
|
+
ordering: 'none',
|
|
675
|
+
priorities: false,
|
|
676
|
+
},
|
|
677
|
+
isConnected: () => true,
|
|
678
|
+
connect: mock(async () => { }),
|
|
679
|
+
disconnect: mock(async () => { }),
|
|
680
|
+
send: mock(async () => 'race-transport'),
|
|
681
|
+
subscribe: mock(async (queueName, handler) => {
|
|
682
|
+
if (queueName === 'matador.test.notifications') {
|
|
683
|
+
await secondSubscribeGate;
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
capturedHandler = handler;
|
|
687
|
+
}
|
|
688
|
+
return { unsubscribe: mock(async () => { }), isActive: true };
|
|
689
|
+
}),
|
|
690
|
+
applyTopology: mock(async () => { }),
|
|
691
|
+
complete: mock(async () => { }),
|
|
692
|
+
};
|
|
693
|
+
matador = new Matador({
|
|
694
|
+
transport: raceTransport,
|
|
695
|
+
topology,
|
|
696
|
+
schema,
|
|
697
|
+
consumeFrom: ['events', 'notifications'],
|
|
698
|
+
});
|
|
699
|
+
const startPromise = matador.start();
|
|
700
|
+
// Wait for the first queue's subscribe() to resolve and capture its
|
|
701
|
+
// handler, while the second queue's subscribe() is still pending.
|
|
702
|
+
while (!capturedHandler) {
|
|
703
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
704
|
+
}
|
|
705
|
+
const envelope = createDummyEnvelope(new UserCreatedEvent({ userId: '123', email: 'test@example.com' }), { targetSubscriber: 'handle-user' });
|
|
706
|
+
await capturedHandler?.(envelope, {
|
|
707
|
+
handle: 'msg-1',
|
|
708
|
+
redelivered: false,
|
|
709
|
+
attemptNumber: 1,
|
|
710
|
+
deliveryCount: 1,
|
|
711
|
+
sourceQueue: 'matador.test.events',
|
|
712
|
+
sourceTransport: 'race-transport',
|
|
713
|
+
});
|
|
714
|
+
expect(sendError).toBeUndefined();
|
|
715
|
+
releaseSecondSubscribe?.();
|
|
716
|
+
await startPromise;
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
describe('self-dispatch during graceful shutdown (stopReceiving)', () => {
|
|
720
|
+
it('LOCAL transport only: a self-dispatched follow-up should still be delivered after stopReceiving()', async () => {
|
|
721
|
+
const topology = TopologyBuilder.create()
|
|
722
|
+
.withNamespace('test')
|
|
723
|
+
.addQueue('events')
|
|
724
|
+
.build();
|
|
725
|
+
const received = [];
|
|
726
|
+
let releaseGate;
|
|
727
|
+
const gate = new Promise((resolve) => {
|
|
728
|
+
releaseGate = resolve;
|
|
729
|
+
});
|
|
730
|
+
let markStarted;
|
|
731
|
+
const started = new Promise((resolve) => {
|
|
732
|
+
markStarted = resolve;
|
|
733
|
+
});
|
|
734
|
+
const stepOneSub = createSubscriber({
|
|
735
|
+
name: 'step-one-handler',
|
|
736
|
+
description: 'Handles step one',
|
|
737
|
+
callback: async (envelope, context) => {
|
|
738
|
+
markStarted?.();
|
|
739
|
+
await gate;
|
|
740
|
+
await context.matador.send(StepTwoEvent, { id: envelope.data.id });
|
|
741
|
+
},
|
|
742
|
+
});
|
|
743
|
+
const stepTwoSub = createSubscriber({
|
|
744
|
+
name: 'step-two-handler',
|
|
745
|
+
description: 'Handles step two',
|
|
746
|
+
callback: async (envelope) => {
|
|
747
|
+
received.push(envelope.data.id);
|
|
748
|
+
},
|
|
749
|
+
});
|
|
750
|
+
const schema = {
|
|
751
|
+
[StepOneEvent.key]: [StepOneEvent, [stepOneSub]],
|
|
752
|
+
[StepTwoEvent.key]: [StepTwoEvent, [stepTwoSub]],
|
|
753
|
+
};
|
|
754
|
+
matador = new Matador({
|
|
755
|
+
transport,
|
|
756
|
+
topology,
|
|
757
|
+
schema,
|
|
758
|
+
consumeFrom: ['events'],
|
|
759
|
+
});
|
|
760
|
+
await matador.start();
|
|
761
|
+
void matador.send(StepOneEvent, { id: 'abc' });
|
|
762
|
+
await started;
|
|
763
|
+
// Graceful shutdown begins while step-one is still in flight.
|
|
764
|
+
await matador.stopReceiving();
|
|
765
|
+
// The in-flight handler now self-dispatches its follow-up event.
|
|
766
|
+
releaseGate?.();
|
|
767
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
768
|
+
// LocalTransport is process-local — no other consumer could ever pick
|
|
769
|
+
// this up, so it should still be delivered here.
|
|
770
|
+
expect(received).toEqual(['abc']);
|
|
771
|
+
});
|
|
772
|
+
it('MULTI transport (external primary + local fallback): a dispatched event that falls back to local should still be delivered after stopReceiving()', async () => {
|
|
773
|
+
const topology = TopologyBuilder.create()
|
|
774
|
+
.withNamespace('test')
|
|
775
|
+
.addQueue('events')
|
|
776
|
+
.build();
|
|
777
|
+
const received = [];
|
|
778
|
+
let releaseGate;
|
|
779
|
+
const gate = new Promise((resolve) => {
|
|
780
|
+
releaseGate = resolve;
|
|
781
|
+
});
|
|
782
|
+
let markStarted;
|
|
783
|
+
const started = new Promise((resolve) => {
|
|
784
|
+
markStarted = resolve;
|
|
785
|
+
});
|
|
786
|
+
// Always-failing "external" transport, forcing every send to fall
|
|
787
|
+
// back to the local transport below.
|
|
788
|
+
const externalMock = {
|
|
789
|
+
name: 'rabbitmq',
|
|
790
|
+
capabilities: {
|
|
791
|
+
deliveryModes: ['at-least-once'],
|
|
792
|
+
delayedMessages: false,
|
|
793
|
+
deadLetterRouting: 'native',
|
|
794
|
+
attemptTracking: true,
|
|
795
|
+
concurrencyModel: 'prefetch',
|
|
796
|
+
ordering: 'none',
|
|
797
|
+
priorities: false,
|
|
798
|
+
},
|
|
799
|
+
isConnected: () => true,
|
|
800
|
+
connect: mock(async () => { }),
|
|
801
|
+
disconnect: mock(async () => { }),
|
|
802
|
+
send: mock(async () => {
|
|
803
|
+
throw new Error('RabbitMQ down');
|
|
804
|
+
}),
|
|
805
|
+
subscribe: mock(async () => ({
|
|
806
|
+
unsubscribe: mock(async () => { }),
|
|
807
|
+
isActive: true,
|
|
808
|
+
})),
|
|
809
|
+
applyTopology: mock(async () => { }),
|
|
810
|
+
complete: mock(async () => { }),
|
|
811
|
+
};
|
|
812
|
+
const localTransport = new LocalTransport();
|
|
813
|
+
const multiTransport = new MultiTransport({
|
|
814
|
+
transports: [externalMock, localTransport],
|
|
815
|
+
});
|
|
816
|
+
const stepOneSub = createSubscriber({
|
|
817
|
+
name: 'step-one-handler',
|
|
818
|
+
description: 'Handles step one',
|
|
819
|
+
callback: async (envelope, context) => {
|
|
820
|
+
markStarted?.();
|
|
821
|
+
await gate;
|
|
822
|
+
await context.matador.send(StepTwoEvent, { id: envelope.data.id });
|
|
823
|
+
},
|
|
824
|
+
});
|
|
825
|
+
const stepTwoSub = createSubscriber({
|
|
826
|
+
name: 'step-two-handler',
|
|
827
|
+
description: 'Handles step two',
|
|
828
|
+
callback: async (envelope) => {
|
|
829
|
+
received.push(envelope.data.id);
|
|
830
|
+
},
|
|
831
|
+
});
|
|
832
|
+
const schema = {
|
|
833
|
+
[StepOneEvent.key]: [StepOneEvent, [stepOneSub]],
|
|
834
|
+
[StepTwoEvent.key]: [StepTwoEvent, [stepTwoSub]],
|
|
835
|
+
};
|
|
836
|
+
matador = new Matador({
|
|
837
|
+
transport: multiTransport,
|
|
838
|
+
topology,
|
|
839
|
+
schema,
|
|
840
|
+
consumeFrom: ['events'],
|
|
841
|
+
});
|
|
842
|
+
await matador.start();
|
|
843
|
+
void matador.send(StepOneEvent, { id: 'abc' });
|
|
844
|
+
await started;
|
|
845
|
+
await matador.stopReceiving();
|
|
846
|
+
releaseGate?.();
|
|
847
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
848
|
+
// The follow-up falls back to the local transport. Local is
|
|
849
|
+
// process-local — no other consumer could ever pick it up — so it
|
|
850
|
+
// should still be delivered here, even though the external transport's
|
|
851
|
+
// own subscription was (correctly) cut off immediately.
|
|
852
|
+
expect(received).toEqual(['abc']);
|
|
853
|
+
});
|
|
854
|
+
it('RABBIT-like (external) transport only: send() after stopReceiving() should still succeed regardless of local subscription state', async () => {
|
|
855
|
+
const topology = TopologyBuilder.create()
|
|
856
|
+
.withNamespace('test')
|
|
857
|
+
.addQueue('events')
|
|
858
|
+
.build();
|
|
859
|
+
const subscriber = createSubscriber({
|
|
860
|
+
name: 'step-one-handler',
|
|
861
|
+
description: 'Handles step one',
|
|
862
|
+
callback: async () => { },
|
|
863
|
+
});
|
|
864
|
+
const schema = {
|
|
865
|
+
[StepOneEvent.key]: [StepOneEvent, [subscriber]],
|
|
866
|
+
};
|
|
867
|
+
const externalTransport = {
|
|
868
|
+
name: 'rabbitmq',
|
|
869
|
+
capabilities: {
|
|
870
|
+
deliveryModes: ['at-least-once'],
|
|
871
|
+
delayedMessages: false,
|
|
872
|
+
deadLetterRouting: 'native',
|
|
873
|
+
attemptTracking: true,
|
|
874
|
+
concurrencyModel: 'prefetch',
|
|
875
|
+
ordering: 'none',
|
|
876
|
+
priorities: false,
|
|
877
|
+
},
|
|
878
|
+
isConnected: () => true,
|
|
879
|
+
connect: mock(async () => { }),
|
|
880
|
+
disconnect: mock(async () => { }),
|
|
881
|
+
send: mock(async () => 'rabbitmq'),
|
|
882
|
+
subscribe: mock(async () => ({
|
|
883
|
+
unsubscribe: mock(async () => { }),
|
|
884
|
+
isActive: true,
|
|
885
|
+
})),
|
|
886
|
+
applyTopology: mock(async () => { }),
|
|
887
|
+
complete: mock(async () => { }),
|
|
888
|
+
};
|
|
889
|
+
matador = new Matador({
|
|
890
|
+
transport: externalTransport,
|
|
891
|
+
topology,
|
|
892
|
+
schema,
|
|
893
|
+
consumeFrom: ['events'],
|
|
894
|
+
});
|
|
895
|
+
await matador.start();
|
|
896
|
+
await matador.stopReceiving();
|
|
897
|
+
const result = await matador.send(StepOneEvent, { id: 'xyz' });
|
|
898
|
+
// A real broker doesn't need an active local consumer to accept a
|
|
899
|
+
// publish — another replica (or this instance, once it stops
|
|
900
|
+
// pretending to be shut down) could still consume it later. This case
|
|
901
|
+
// is not part of the bug — included as a contrast baseline.
|
|
902
|
+
expect(result.subscribersSent).toBe(1);
|
|
903
|
+
expect(result.errors).toHaveLength(0);
|
|
904
|
+
});
|
|
905
|
+
});
|
|
577
906
|
});
|
package/dist/errors/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { HasDescription } from './has-description.js';
|
|
2
2
|
export { hasDescription } from './has-description.js';
|
|
3
3
|
export { assertEvent, DontRetry, DoRetry, EventAssertionError, isAssertionError, isDontRetry, isDoRetry, RetryControlError, } from './retry-errors.js';
|
|
4
|
-
export { MatadorError, isMatadorError, NotStartedError, isNotStartedError, ShutdownInProgressError, TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, SomeSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError, EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError,
|
|
4
|
+
export { MatadorError, isMatadorError, NotStartedError, isNotStartedError, ShutdownInProgressError, TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, SomeSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError, LocalTransportNoActiveSubscriberError, EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError, QueueNotFoundError, UnknownQueueReferenceError, isUnknownQueueReferenceError, InvalidEventError, MessageMaybePoisonedError, isMessageMaybePoisonedError, IdempotentMessageCannotRetryError, isIdempotentMessageCannotRetryError, TimeoutError, } from './matador-errors.js';
|
|
5
5
|
export { CheckpointStoreError, DuplicateIoKeyError, isCheckpointStoreError, isDuplicateIoKeyError, } from './checkpoint-errors.js';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EACL,WAAW,EACX,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,SAAS,EACT,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAEL,YAAY,EACZ,cAAc,EAEd,eAAe,EACf,iBAAiB,EACjB,uBAAuB,EAEvB,0BAA0B,EAC1B,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,gCAAgC,EAChC,qCAAqC,EAErC,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,8BAA8B,EAC9B,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EAErB,kBAAkB,EAClB,0BAA0B,EAC1B,4BAA4B,EAE5B,iBAAiB,EAEjB,yBAAyB,EACzB,2BAA2B,EAC3B,iCAAiC,EACjC,mCAAmC,EAEnC,YAAY,GACb,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC"}
|
package/dist/errors/index.js
CHANGED
|
@@ -6,9 +6,9 @@ MatadorError, isMatadorError,
|
|
|
6
6
|
// Lifecycle errors
|
|
7
7
|
NotStartedError, isNotStartedError, ShutdownInProgressError,
|
|
8
8
|
// Transport errors
|
|
9
|
-
TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, SomeSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError,
|
|
9
|
+
TransportNotConnectedError, isTransportNotConnectedError, TransportClosedError, TransportSendError, SomeSendError, AllTransportsFailedError, DelayedMessagesNotSupportedError, LocalTransportNoActiveSubscriberError,
|
|
10
10
|
// Schema & configuration errors
|
|
11
|
-
EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError,
|
|
11
|
+
EventNotRegisteredError, isEventNotRegisteredError, SubscriberNotRegisteredError, isSubscriberNotRegisteredError, NoSubscribersExistError, InvalidSchemaError, SubscriberIsStubError,
|
|
12
12
|
// Queue errors
|
|
13
13
|
QueueNotFoundError, UnknownQueueReferenceError, isUnknownQueueReferenceError,
|
|
14
14
|
// Event validation errors
|
|
@@ -98,6 +98,16 @@ export declare class DelayedMessagesNotSupportedError extends MatadorError {
|
|
|
98
98
|
readonly description: string;
|
|
99
99
|
constructor(transportName: string);
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Thrown when a LocalTransport is sent a message for a queue with no active
|
|
103
|
+
* subscriber in the current process (e.g. the subscriber is a SubscriberStub
|
|
104
|
+
* implemented in another service, or matador.start() hasn't subscribed yet).
|
|
105
|
+
*/
|
|
106
|
+
export declare class LocalTransportNoActiveSubscriberError extends MatadorError {
|
|
107
|
+
readonly queue: string;
|
|
108
|
+
readonly description: string;
|
|
109
|
+
constructor(queue: string);
|
|
110
|
+
}
|
|
101
111
|
/**
|
|
102
112
|
* Thrown when an event is not registered in the schema.
|
|
103
113
|
*/
|
|
@@ -139,14 +149,6 @@ export declare class SubscriberIsStubError extends MatadorError {
|
|
|
139
149
|
readonly description: string;
|
|
140
150
|
constructor(subscriberName: string);
|
|
141
151
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Thrown when a LocalTransport tries to process a stub subscriber.
|
|
144
|
-
*/
|
|
145
|
-
export declare class LocalTransportCannotProcessStubError extends MatadorError {
|
|
146
|
-
readonly subscriberName: string;
|
|
147
|
-
readonly description: string;
|
|
148
|
-
constructor(subscriberName: string);
|
|
149
|
-
}
|
|
150
152
|
/**
|
|
151
153
|
* Thrown when a subscriber's `targetQueue` or a `consumeFrom` entry references
|
|
152
154
|
* a queue that was never declared in the topology.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matador-errors.d.ts","sourceRoot":"","sources":["../../src/errors/matador-errors.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"matador-errors.d.ts","sourceRoot":"","sources":["../../src/errors/matador-errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -168,6 +168,24 @@ export class DelayedMessagesNotSupportedError extends MatadorError {
|
|
|
168
168
|
this.transportName = transportName;
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Thrown when a LocalTransport is sent a message for a queue with no active
|
|
173
|
+
* subscriber in the current process (e.g. the subscriber is a SubscriberStub
|
|
174
|
+
* implemented in another service, or matador.start() hasn't subscribed yet).
|
|
175
|
+
*/
|
|
176
|
+
export class LocalTransportNoActiveSubscriberError extends MatadorError {
|
|
177
|
+
queue;
|
|
178
|
+
description = 'The LocalTransport has no active subscriber for this queue in the current process, ' +
|
|
179
|
+
'so it cannot guarantee delivery. ' +
|
|
180
|
+
'ACTION: If the subscriber is a SubscriberStub (implemented in another service), ' +
|
|
181
|
+
'the local transport can never deliver it locally — a distributed transport like ' +
|
|
182
|
+
'RabbitMQ is required. If the subscriber should run in this process, ensure ' +
|
|
183
|
+
'matador.start() has subscribed to this queue before sending.';
|
|
184
|
+
constructor(queue) {
|
|
185
|
+
super(`LocalTransport has no active subscriber for queue "${queue}"; message cannot be delivered.`);
|
|
186
|
+
this.queue = queue;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
171
189
|
// ============================================================================
|
|
172
190
|
// Schema & Configuration Errors
|
|
173
191
|
// ============================================================================
|
|
@@ -248,20 +266,6 @@ export class SubscriberIsStubError extends MatadorError {
|
|
|
248
266
|
this.subscriberName = subscriberName;
|
|
249
267
|
}
|
|
250
268
|
}
|
|
251
|
-
/**
|
|
252
|
-
* Thrown when a LocalTransport tries to process a stub subscriber.
|
|
253
|
-
*/
|
|
254
|
-
export class LocalTransportCannotProcessStubError extends MatadorError {
|
|
255
|
-
subscriberName;
|
|
256
|
-
description = 'The LocalTransport cannot process events for SubscriberStubs. ' +
|
|
257
|
-
'ACTION: SubscriberStubs represent remote implementations that only RabbitMQ can route. ' +
|
|
258
|
-
'If using LocalTransport for testing, provide mock implementations instead of stubs. ' +
|
|
259
|
-
'For production fallback scenarios, be aware that stub-targeted events will be dropped.';
|
|
260
|
-
constructor(subscriberName) {
|
|
261
|
-
super(`LocalTransport cannot process stub subscriber "${subscriberName}". Stub subscribers require a distributed transport like RabbitMQ.`);
|
|
262
|
-
this.subscriberName = subscriberName;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
269
|
// ============================================================================
|
|
266
270
|
// Queue Errors
|
|
267
271
|
// ============================================================================
|