comq 0.20.0 → 0.20.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.
package/features/silence.feature
CHANGED
|
@@ -57,6 +57,7 @@ Feature: Silent Connection Tolerance
|
|
|
57
57
|
Scenario: Reporting that there is nowhere left to publish
|
|
58
58
|
Given an active sharded connection
|
|
59
59
|
And a producer replying `echo` queue
|
|
60
|
-
When the network goes silent
|
|
60
|
+
When the network goes silent and refuses new connections
|
|
61
61
|
Then publishing is paused within 10 seconds
|
|
62
|
-
|
|
62
|
+
When the network admits new connections
|
|
63
|
+
Then publishing is resumed within 10 seconds
|
|
@@ -26,6 +26,24 @@ When('the network goes silent',
|
|
|
26
26
|
silence.call(this)
|
|
27
27
|
})
|
|
28
28
|
|
|
29
|
+
When('the network goes silent and refuses new connections',
|
|
30
|
+
/**
|
|
31
|
+
* @this {comq.features.Context}
|
|
32
|
+
*/
|
|
33
|
+
function () {
|
|
34
|
+
for (const network of this.networks) network.refuse()
|
|
35
|
+
|
|
36
|
+
silence.call(this)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
When('the network admits new connections',
|
|
40
|
+
/**
|
|
41
|
+
* @this {comq.features.Context}
|
|
42
|
+
*/
|
|
43
|
+
function () {
|
|
44
|
+
for (const network of this.networks) network.admit()
|
|
45
|
+
})
|
|
46
|
+
|
|
29
47
|
When('the silent connection is let go',
|
|
30
48
|
/**
|
|
31
49
|
* @this {comq.features.Context}
|
|
@@ -23,6 +23,8 @@ class Network {
|
|
|
23
23
|
/** @type {number} */
|
|
24
24
|
#port
|
|
25
25
|
|
|
26
|
+
#refusing = false
|
|
27
|
+
|
|
26
28
|
/**
|
|
27
29
|
* @param {number} [n] broker index
|
|
28
30
|
*/
|
|
@@ -51,6 +53,18 @@ class Network {
|
|
|
51
53
|
for (const tunnel of this.#tunnels) tunnel.silent = true
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
/**
|
|
57
|
+
* A connection established from now on is closed as soon as it is accepted, so
|
|
58
|
+
* a connection that is lost stays lost until the network admits it.
|
|
59
|
+
*/
|
|
60
|
+
refuse () {
|
|
61
|
+
this.#refusing = true
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
admit () {
|
|
65
|
+
this.#refusing = false
|
|
66
|
+
}
|
|
67
|
+
|
|
54
68
|
/**
|
|
55
69
|
* Closes the tunnels that went silent, at both ends, so the broker learns that the
|
|
56
70
|
* connection it was still holding is gone — the moment its heartbeat would otherwise tell it.
|
|
@@ -69,6 +83,8 @@ class Network {
|
|
|
69
83
|
* @param {net.Socket} client
|
|
70
84
|
*/
|
|
71
85
|
#tunnel = (client) => {
|
|
86
|
+
if (this.#refusing) return client.destroy()
|
|
87
|
+
|
|
72
88
|
const upstream = net.connect(this.#port, this.#host)
|
|
73
89
|
|
|
74
90
|
/** @type {comq.features.Tunnel} */
|
package/package.json
CHANGED
package/source/connection.js
CHANGED
|
@@ -371,6 +371,8 @@ const SHUTDOWN_MS = 5_000
|
|
|
371
371
|
|
|
372
372
|
const SOCKET_OPTIONS = {
|
|
373
373
|
timeout: CONNECT_MS,
|
|
374
|
+
// a message is written once and is small, which is what Nagle's algorithm holds back
|
|
375
|
+
noDelay: true,
|
|
374
376
|
// a peer that went away without a word is noticed by the kernel as well
|
|
375
377
|
keepAlive: true,
|
|
376
378
|
keepAliveDelay: KEEPALIVE_MS
|
package/test/connection.test.js
CHANGED
|
@@ -684,6 +684,13 @@ describe('heartbeat', () => {
|
|
|
684
684
|
expect(amqplib.connect)
|
|
685
685
|
.toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ keepAlive: true }))
|
|
686
686
|
})
|
|
687
|
+
|
|
688
|
+
it('should send without delay', async () => {
|
|
689
|
+
await connection.open()
|
|
690
|
+
|
|
691
|
+
expect(amqplib.connect)
|
|
692
|
+
.toHaveBeenCalledWith(expect.any(String), expect.objectContaining({ noDelay: true }))
|
|
693
|
+
})
|
|
687
694
|
})
|
|
688
695
|
|
|
689
696
|
describe('close', () => {
|