aedes 0.51.3 → 1.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.
- package/.claude/settings.local.json +12 -0
- package/.github/actions/sticky-pr-comment/action.yml +55 -0
- package/.github/workflows/benchmark-compare-serial.yml +60 -0
- package/.github/workflows/ci.yml +12 -17
- package/.release-it.json +18 -0
- package/.taprc +15 -6
- package/README.md +6 -4
- package/aedes.d.ts +0 -6
- package/aedes.js +270 -242
- package/benchmarks/README.md +33 -0
- package/benchmarks/pingpong.js +94 -25
- package/benchmarks/receiver.js +77 -0
- package/benchmarks/report.js +150 -0
- package/benchmarks/runBenchmarks.js +118 -0
- package/benchmarks/sender.js +86 -0
- package/benchmarks/server.js +19 -18
- package/checkVersion.js +20 -0
- package/docs/Aedes.md +66 -8
- package/docs/Client.md +3 -4
- package/docs/Examples.md +39 -22
- package/docs/MIGRATION.md +50 -0
- package/eslint.config.js +8 -0
- package/example.js +51 -40
- package/examples/clusters/index.js +28 -23
- package/examples/clusters/package.json +10 -6
- package/lib/client.js +405 -306
- package/lib/handlers/connect.js +42 -38
- package/lib/handlers/index.js +9 -11
- package/lib/handlers/ping.js +2 -3
- package/lib/handlers/puback.js +5 -5
- package/lib/handlers/publish.js +29 -14
- package/lib/handlers/pubrec.js +9 -17
- package/lib/handlers/pubrel.js +34 -25
- package/lib/handlers/subscribe.js +47 -43
- package/lib/handlers/unsubscribe.js +16 -19
- package/lib/qos-packet.js +14 -17
- package/lib/utils.js +5 -12
- package/lib/write.js +4 -5
- package/package.json +139 -136
- package/test/auth.js +468 -804
- package/test/basic.js +613 -575
- package/test/bridge.js +44 -40
- package/test/client-pub-sub.js +531 -504
- package/test/close_socket_by_other_party.js +137 -102
- package/test/connect.js +487 -484
- package/test/drain-timeout.js +593 -0
- package/test/drain-toxiproxy.js +620 -0
- package/test/events.js +173 -145
- package/test/helper.js +351 -73
- package/test/keep-alive.js +40 -67
- package/test/meta.js +257 -210
- package/test/not-blocking.js +93 -197
- package/test/qos1.js +464 -554
- package/test/qos2.js +308 -393
- package/test/regr-21.js +39 -21
- package/test/require.cjs +22 -0
- package/test/retain.js +349 -398
- package/test/topics.js +176 -183
- package/test/types/aedes.test-d.ts +4 -8
- package/test/will.js +310 -428
- package/types/instance.d.ts +40 -35
- package/types/packet.d.ts +10 -10
- package/.coveralls.yml +0 -1
- package/benchmarks/bombing.js +0 -34
- package/benchmarks/bombingQoS1.js +0 -36
- package/benchmarks/throughputCounter.js +0 -23
- package/benchmarks/throughputCounterQoS1.js +0 -33
- package/types/.eslintrc.json +0 -47
package/test/not-blocking.js
CHANGED
|
@@ -1,231 +1,127 @@
|
|
|
1
|
-
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import { createServer } from 'node:net'
|
|
3
|
+
import { once } from 'node:events'
|
|
4
|
+
import mqtt from 'mqtt'
|
|
5
|
+
import { Aedes } from '../aedes.js'
|
|
2
6
|
|
|
3
|
-
|
|
4
|
-
const EventEmitter = require('events')
|
|
5
|
-
const mqtt = require('mqtt')
|
|
6
|
-
const net = require('net')
|
|
7
|
-
const Faketimers = require('@sinonjs/fake-timers')
|
|
8
|
-
const aedes = require('../')
|
|
9
|
-
|
|
10
|
-
test('connect 500 concurrent clients', function (t) {
|
|
7
|
+
test('connect 500 concurrent clients', async (t) => {
|
|
11
8
|
t.plan(3)
|
|
12
9
|
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
|
|
10
|
+
const broker = await Aedes.createBroker({ drainTimeout: 0 }) // Disable for high-load test
|
|
11
|
+
const server = createServer(broker.handle)
|
|
12
|
+
t.after(() => {
|
|
13
|
+
broker.close()
|
|
14
|
+
server.close()
|
|
15
|
+
})
|
|
16
16
|
const total = 500
|
|
17
17
|
|
|
18
|
-
server.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let connected = 0
|
|
27
|
-
const clients = []
|
|
28
|
-
clock.setTimeout(function () {
|
|
29
|
-
t.equal(clients.length, total)
|
|
30
|
-
t.equal(connected, total)
|
|
31
|
-
while (clients.length) {
|
|
32
|
-
clients.shift().end()
|
|
33
|
-
}
|
|
34
|
-
}, total)
|
|
35
|
-
|
|
36
|
-
evt.on('finish', function () {
|
|
37
|
-
if (clients.length === 0) {
|
|
38
|
-
broker.close()
|
|
39
|
-
server.close()
|
|
40
|
-
}
|
|
18
|
+
server.on('error', (err) => {
|
|
19
|
+
console.log('server error', err)
|
|
20
|
+
})
|
|
21
|
+
await new Promise(resolve => {
|
|
22
|
+
server.listen(0, (err) => {
|
|
23
|
+
t.assert.ok(!err, 'no error')
|
|
24
|
+
resolve()
|
|
41
25
|
})
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < total; i++) {
|
|
44
|
-
clients[i] = mqtt.connect({
|
|
45
|
-
port,
|
|
46
|
-
keepalive: 0,
|
|
47
|
-
reconnectPeriod: 100
|
|
48
|
-
}).on('connect', function () {
|
|
49
|
-
connected++
|
|
50
|
-
if ((connected % (total / 10)) === 0) {
|
|
51
|
-
console.log('connected', connected)
|
|
52
|
-
}
|
|
53
|
-
clock.tick(1)
|
|
54
|
-
}).on('close', function () {
|
|
55
|
-
evt.emit('finish')
|
|
56
|
-
})
|
|
57
|
-
}
|
|
58
26
|
})
|
|
59
|
-
})
|
|
60
27
|
|
|
61
|
-
|
|
62
|
-
t.plan(3)
|
|
28
|
+
const port = server.address().port
|
|
63
29
|
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
const server = net.createServer(broker.handle)
|
|
67
|
-
const total = 10000
|
|
68
|
-
let sent = 0
|
|
69
|
-
let received = 0
|
|
30
|
+
let connected = 0
|
|
31
|
+
const clients = []
|
|
70
32
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const clock = Faketimers.createClock()
|
|
75
|
-
t.teardown(clock.reset.bind(clock))
|
|
76
|
-
|
|
77
|
-
const clockId = clock.setTimeout(finish, total)
|
|
78
|
-
|
|
79
|
-
const port = server.address().port
|
|
80
|
-
|
|
81
|
-
const publisher = mqtt.connect({
|
|
33
|
+
// start at 1 to see the total in the console.log
|
|
34
|
+
for (let i = 1; i <= total; i++) {
|
|
35
|
+
clients[i] = await mqtt.connectAsync({
|
|
82
36
|
port,
|
|
83
37
|
keepalive: 0
|
|
84
|
-
}).on('error', function (err) {
|
|
85
|
-
clock.clearTimeout(clockId)
|
|
86
|
-
t.fail(err)
|
|
87
38
|
})
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
function immediatePublish () {
|
|
92
|
-
setImmediate(publish)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function publish () {
|
|
96
|
-
if (sent === total) {
|
|
97
|
-
publisher.end()
|
|
98
|
-
} else {
|
|
99
|
-
sent++
|
|
100
|
-
publisher.publish('test', 'payload', immediatePublish)
|
|
101
|
-
}
|
|
39
|
+
if ((i % (total / 10)) === 0) {
|
|
40
|
+
console.log('connected', i)
|
|
102
41
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
clock.clearTimeout(clockId)
|
|
110
|
-
t.fail(err)
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
subscriber.subscribe('test', publish)
|
|
114
|
-
|
|
115
|
-
subscriber.on('message', function () {
|
|
116
|
-
if (received % (total / 10) === 0) {
|
|
117
|
-
console.log('sent / received', sent, received)
|
|
118
|
-
}
|
|
119
|
-
received++
|
|
120
|
-
clock.tick(1)
|
|
121
|
-
})
|
|
122
|
-
subscriber.on('close', function () {
|
|
123
|
-
evt.emit('finish')
|
|
124
|
-
})
|
|
42
|
+
}
|
|
43
|
+
// check to see if they are all still alive
|
|
44
|
+
// and end them
|
|
45
|
+
for (let i = 1; i <= total; i++) {
|
|
46
|
+
if (clients[i].connected) {
|
|
47
|
+
connected++
|
|
125
48
|
}
|
|
49
|
+
await clients[i].endAsync(true)
|
|
50
|
+
}
|
|
51
|
+
t.assert.equal(clients.length, total + 1) // because we start at 1
|
|
52
|
+
t.assert.equal(connected, total)
|
|
53
|
+
})
|
|
126
54
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
55
|
+
for (const [title, brokerOpts, subscription] of
|
|
56
|
+
[
|
|
57
|
+
['after a subscription', {}, 'test'],
|
|
58
|
+
['with overlapping subscription', { concurrency: 15 }, ['#', 'test']]
|
|
59
|
+
]) {
|
|
60
|
+
test(`do not block ${title}`, async (t) => {
|
|
61
|
+
t.plan(3)
|
|
62
|
+
|
|
63
|
+
const broker = await Aedes.createBroker({ ...brokerOpts, drainTimeout: 0 }) // Disable for high-throughput test
|
|
64
|
+
const server = createServer(broker.handle)
|
|
65
|
+
t.after(() => {
|
|
133
66
|
broker.close()
|
|
134
67
|
server.close()
|
|
135
|
-
t.equal(total, sent, 'messages sent')
|
|
136
|
-
t.equal(total, received, 'messages received')
|
|
137
68
|
})
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const evt = new EventEmitter()
|
|
149
|
-
const broker = aedes({ concurrency: 15 })
|
|
150
|
-
const server = net.createServer(broker.handle)
|
|
151
|
-
const total = 10000
|
|
152
|
-
let sent = 0
|
|
153
|
-
let received = 0
|
|
154
|
-
|
|
155
|
-
server.listen(0, function (err) {
|
|
156
|
-
t.error(err, 'no error')
|
|
157
|
-
|
|
158
|
-
const clock = Faketimers.createClock()
|
|
159
|
-
t.teardown(clock.reset.bind(clock))
|
|
160
|
-
|
|
161
|
-
const clockId = clock.setTimeout(finish, total)
|
|
162
|
-
|
|
163
|
-
const port = server.address().port
|
|
164
|
-
|
|
165
|
-
const publisher = mqtt.connect({
|
|
166
|
-
port,
|
|
167
|
-
keepalive: 0
|
|
168
|
-
}).on('error', function (err) {
|
|
169
|
-
clock.clearTimeout(clockId)
|
|
170
|
-
t.fail(err)
|
|
69
|
+
const total = 10000
|
|
70
|
+
let sent = 0
|
|
71
|
+
let received = 0
|
|
72
|
+
|
|
73
|
+
await new Promise(resolve => {
|
|
74
|
+
server.listen(0, err => {
|
|
75
|
+
t.assert.ok(!err, 'no error')
|
|
76
|
+
resolve()
|
|
77
|
+
})
|
|
171
78
|
})
|
|
79
|
+
const port = server.address().port
|
|
80
|
+
let publisher = null
|
|
172
81
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
function immediatePublish (e) {
|
|
176
|
-
setImmediate(publish)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function publish () {
|
|
82
|
+
const publish = () => {
|
|
180
83
|
if (sent === total) {
|
|
181
84
|
publisher.end()
|
|
182
85
|
} else {
|
|
183
86
|
sent++
|
|
184
|
-
publisher.publish('test', 'payload',
|
|
87
|
+
publisher.publish('test', 'payload', () => setImmediate(publish))
|
|
185
88
|
}
|
|
186
89
|
}
|
|
187
90
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
clock.clearTimeout(clockId)
|
|
194
|
-
t.fail(err)
|
|
195
|
-
})
|
|
91
|
+
const subscriber = await mqtt.connectAsync({
|
|
92
|
+
port,
|
|
93
|
+
keepalive: 0,
|
|
94
|
+
clientId: 'subscriber'
|
|
95
|
+
})
|
|
196
96
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
})
|
|
201
|
-
})
|
|
97
|
+
subscriber.on('error', err => {
|
|
98
|
+
t.assert.fail(err)
|
|
99
|
+
})
|
|
202
100
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
101
|
+
subscriber.on('message', () => {
|
|
102
|
+
if (received % (total / 10) === 0) {
|
|
103
|
+
console.log('sent / received', sent, received)
|
|
104
|
+
}
|
|
105
|
+
received++
|
|
106
|
+
if (received === total) {
|
|
107
|
+
// Close subscriber when all messages received
|
|
108
|
+
setImmediate(() => subscriber.end())
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
await subscriber.subscribeAsync(subscription)
|
|
214
112
|
|
|
215
|
-
publisher.
|
|
216
|
-
|
|
217
|
-
|
|
113
|
+
publisher = await mqtt.connectAsync({
|
|
114
|
+
port,
|
|
115
|
+
keepalive: 0,
|
|
116
|
+
clientId: 'publisher'
|
|
218
117
|
})
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
broker.close()
|
|
222
|
-
server.close()
|
|
223
|
-
t.equal(total, sent, 'messages sent')
|
|
224
|
-
t.equal(total, received, 'messages received')
|
|
118
|
+
publisher.on('error', err => {
|
|
119
|
+
t.assert.fail(err)
|
|
225
120
|
})
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
121
|
+
publish()
|
|
122
|
+
|
|
123
|
+
await once(subscriber, 'close')
|
|
124
|
+
t.assert.equal(total, sent, 'messages sent')
|
|
125
|
+
t.assert.equal(total, received, 'messages received')
|
|
230
126
|
})
|
|
231
|
-
}
|
|
127
|
+
}
|