comq 0.17.0 → 0.18.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/.github/workflows/{dev.yaml → features.yaml} +14 -3
- package/discussions/poison-message-handling.md +1120 -0
- package/docs/headers.md +36 -0
- package/features/events.poison.feature +32 -12
- package/features/events.routed.feature +6 -0
- package/features/steps/context.js +18 -2
- package/features/steps/events.js +5 -1
- package/features/steps/poison.js +65 -4
- package/package.json +1 -1
- package/readme.md +106 -14
- package/source/channel.js +210 -30
- package/source/connect.js +31 -21
- package/source/connection.js +11 -2
- package/source/events.js +1 -1
- package/source/shards/channel.js +8 -0
- package/source/singleton.js +47 -4
- package/source/topology/event.json +7 -1
- package/source/topology/request.json +7 -1
- package/test/assert.test.js +2 -2
- package/test/channel.fixtures.js +2 -1
- package/test/channel.routed.test.js +7 -3
- package/test/channel.test.js +593 -5
- package/test/connect.test.js +31 -2
- package/test/helpers.js +15 -0
- package/test/io.diagnostics.test.js +1 -1
- package/test/presets.test.js +4 -2
- package/test/shards/channel.test.js +33 -0
- package/test/singleton.test.js +1 -1
- package/types/connection.d.ts +6 -1
- package/types/diagnostic.d.ts +1 -1
- package/types/io.d.ts +3 -1
- package/types/topology.d.ts +16 -0
|
@@ -28,7 +28,7 @@ describe.each(['request', 'reply', 'event'])('%s channel events',
|
|
|
28
28
|
* @param {comq.topology.type} type
|
|
29
29
|
*/
|
|
30
30
|
(type) => {
|
|
31
|
-
it.each(['flow', 'drain', 'recover', 'discard', 'pause', 'resume', 'lost', 'remove'])('should re-emit %s',
|
|
31
|
+
it.each(['flow', 'drain', 'recover', 'discard', 'retry', 'pause', 'resume', 'lost', 'remove'])('should re-emit %s',
|
|
32
32
|
/**
|
|
33
33
|
* @param {comq.diagnostics.Event} event
|
|
34
34
|
*/
|
package/test/presets.test.js
CHANGED
|
@@ -8,7 +8,8 @@ it('should define request preset', async () => {
|
|
|
8
8
|
confirms: false,
|
|
9
9
|
durable: true,
|
|
10
10
|
acknowledgments: true,
|
|
11
|
-
persistent: false
|
|
11
|
+
persistent: false,
|
|
12
|
+
delay: [1000, 3000, 5000, 10000]
|
|
12
13
|
})
|
|
13
14
|
})
|
|
14
15
|
|
|
@@ -28,6 +29,7 @@ it('should define event preset', async () => {
|
|
|
28
29
|
confirms: true,
|
|
29
30
|
durable: true,
|
|
30
31
|
acknowledgments: true,
|
|
31
|
-
persistent: true
|
|
32
|
+
persistent: true,
|
|
33
|
+
delay: [1000, 10000, 30000, 90000]
|
|
32
34
|
})
|
|
33
35
|
})
|
|
@@ -718,3 +718,36 @@ async function getCreatedChannels () {
|
|
|
718
718
|
|
|
719
719
|
return await Promise.all(promises)
|
|
720
720
|
}
|
|
721
|
+
|
|
722
|
+
describe('routed', () => {
|
|
723
|
+
const exchange = generate()
|
|
724
|
+
const queue = generate()
|
|
725
|
+
const key = generate()
|
|
726
|
+
const buffer = randomBytes(8)
|
|
727
|
+
const consumer = jest.fn()
|
|
728
|
+
|
|
729
|
+
/** @type {jest.MockedObject<comq.Channel>[]} */
|
|
730
|
+
let channels
|
|
731
|
+
|
|
732
|
+
beforeEach(async () => {
|
|
733
|
+
channel = await create(connections, type)
|
|
734
|
+
channels = await getCreatedChannels()
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
it('should bind using all channels', async () => {
|
|
738
|
+
await channel.bound(exchange, queue, key, consumer)
|
|
739
|
+
|
|
740
|
+
for (const chan of channels) {
|
|
741
|
+
expect(chan.bound).toHaveBeenCalledWith(exchange, queue, key, consumer)
|
|
742
|
+
}
|
|
743
|
+
})
|
|
744
|
+
|
|
745
|
+
it('should route to a single channel', async () => {
|
|
746
|
+
await channel.route(exchange, key, buffer)
|
|
747
|
+
|
|
748
|
+
const used = channels.filter((chan) => chan.route.mock.calls.length > 0)
|
|
749
|
+
|
|
750
|
+
expect(used).toHaveLength(1)
|
|
751
|
+
expect(used[0].route).toHaveBeenCalledWith(exchange, key, buffer, undefined)
|
|
752
|
+
})
|
|
753
|
+
})
|
package/test/singleton.test.js
CHANGED
|
@@ -27,7 +27,7 @@ beforeEach(() => {
|
|
|
27
27
|
|
|
28
28
|
it('should extend Connection', async () => {
|
|
29
29
|
expect(connection).toBeInstanceOf(mock.Connection)
|
|
30
|
-
expect(mock.Connection.ctor).toHaveBeenCalledWith(url)
|
|
30
|
+
expect(mock.Connection.ctor).toHaveBeenCalledWith(url, {})
|
|
31
31
|
})
|
|
32
32
|
|
|
33
33
|
describe('connection', () => {
|
package/types/connection.d.ts
CHANGED
|
@@ -22,7 +22,12 @@ declare namespace comq {
|
|
|
22
22
|
forget(event: _diagnostics.Event, listener: Function): void
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
type Connect =
|
|
25
|
+
type Connect = {
|
|
26
|
+
(...urls: string[]): Promise<_io.IO>
|
|
27
|
+
|
|
28
|
+
/** The trailing argument overrides the topology presets, per channel type. */
|
|
29
|
+
(...args: [...urls: string[], overrides: _topology.Overrides]): Promise<_io.IO>
|
|
30
|
+
}
|
|
26
31
|
|
|
27
32
|
}
|
|
28
33
|
|
package/types/diagnostic.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare namespace comq.diagnostics {
|
|
2
2
|
|
|
3
3
|
type Event = 'open' | 'close' | 'error' | 'reconnect' | 'exhausted' | 'flow' | 'drain' |
|
|
4
|
-
'remove' | 'lost' | 'recover' | 'discard' | 'pause' | 'resume' | 'return'
|
|
4
|
+
'remove' | 'lost' | 'recover' | 'discard' | 'retry' | 'pause' | 'resume' | 'return'
|
|
5
5
|
|
|
6
6
|
interface Diagnosable {
|
|
7
7
|
diagnose(event: Event, listener: Function): void
|
package/types/io.d.ts
CHANGED
|
@@ -103,7 +103,9 @@ declare namespace comq {
|
|
|
103
103
|
|
|
104
104
|
diagnose(event: 'recover', listener: (channel: _topology.type, index?: number) => void): void
|
|
105
105
|
|
|
106
|
-
diagnose(event: 'discard', listener: (channel: _topology.type, message: any, index?: number) => void): void
|
|
106
|
+
diagnose(event: 'discard', listener: (channel: _topology.type, message: any, error: Error, index?: number) => void): void
|
|
107
|
+
|
|
108
|
+
diagnose(event: 'retry', listener: (channel: _topology.type, message: any, error: Error, attempt: number, index?: number) => void): void
|
|
107
109
|
|
|
108
110
|
diagnose(event: 'pause', listener: (channel: _topology.type) => void): void
|
|
109
111
|
|
package/types/topology.d.ts
CHANGED
|
@@ -8,6 +8,11 @@ declare namespace comq {
|
|
|
8
8
|
[K in type]: Topology
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
/** Per channel type overrides of the presets, as passed to `connect`. */
|
|
12
|
+
type Overrides = {
|
|
13
|
+
[K in type]?: Partial<Topology>
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
}
|
|
12
17
|
|
|
13
18
|
type Topology = {
|
|
@@ -16,8 +21,19 @@ declare namespace comq {
|
|
|
16
21
|
durable: boolean
|
|
17
22
|
acknowledgments: boolean
|
|
18
23
|
persistent: boolean
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* How long a failed message waits before it is delivered again, in milliseconds:
|
|
27
|
+
* one entry per retry, so **the length of the ladder is the number of retries** and
|
|
28
|
+
* four rungs is five attempts. A bare number is a ladder of one, hence a single retry.
|
|
29
|
+
*
|
|
30
|
+
* Each distinct value is a retry queue of its own, because the wait is the queue's
|
|
31
|
+
* `x-message-ttl` rather than the message's, and a queue holds one of those.
|
|
32
|
+
*/
|
|
33
|
+
delay: number | number[]
|
|
19
34
|
}
|
|
20
35
|
|
|
21
36
|
}
|
|
22
37
|
|
|
23
38
|
export type type = comq.topology.type
|
|
39
|
+
export type Overrides = comq.topology.Overrides
|