Skip to content

Commit 661d4ca

Browse files
f3rnoJacobPlaster
authored andcommitted
(fix) internal flag persistence and affected tests, closes #521
1 parent abbd3c1 commit 661d4ca

File tree

2 files changed

+161
-75
lines changed

2 files changed

+161
-75
lines changed

lib/transports/ws2.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class WSv2 extends EventEmitter {
127127
this._subscriptionRefs = {}
128128
this._channelMap = {}
129129
this._orderBooks = {}
130-
this._enabledFlags = 0
130+
this._enabledFlags = this._seqAudit ? FLAGS.SEQ_ALL : 0
131131
this._eventCallbacks = new CbQ()
132132
this._isAuthenticated = false
133133
this._wasEverAuthenticated = false // used for auto-auth on reconnect
@@ -214,16 +214,19 @@ class WSv2 extends EventEmitter {
214214
this._orderBooks = {}
215215

216216
this._ws.on('message', this._onWSMessage)
217-
this._ws.on('open', this._onWSOpen)
218217
this._ws.on('error', this._onWSError)
219218
this._ws.on('close', this._onWSClose)
220219

221-
if (this._seqAudit) {
222-
this._ws.once('open', this.enableSequencing.bind(this))
223-
}
224-
225220
return new Promise((resolve, reject) => {
226-
this._ws.once('open', () => {
221+
this._ws.on('open', () => {
222+
if (this._enabledFlags !== 0) {
223+
this.sendEnabledFlags()
224+
}
225+
226+
// call manually instead of binding to open event so it fires at the
227+
// right time
228+
this._onWSOpen()
229+
227230
debug('connected')
228231
resolve()
229232
})
@@ -468,7 +471,6 @@ class WSv2 extends EventEmitter {
468471
this._isOpen = true
469472
this._isReconnecting = false
470473
this._packetWDLastTS = Date.now()
471-
this._enabledFlags = 0
472474
this._lastAuthSeq = -1
473475
this._lastPubSeq = -1
474476
this.emit('open')
@@ -1382,12 +1384,24 @@ class WSv2 extends EventEmitter {
13821384
* @return {Promise} p
13831385
*/
13841386
enableFlag (flag) {
1387+
this._enabledFlags = this._enabledFlags | flag
1388+
1389+
if (this._isOpen) {
1390+
this.sendEnabledFlags()
1391+
return this._getEventPromise(this._getConfigEventKey(flag))
1392+
}
1393+
1394+
return Promise.resolve()
1395+
}
1396+
1397+
/**
1398+
* Sends the local flags value to the server, updating the config
1399+
*/
1400+
sendEnabledFlags () {
13851401
this.send({
13861402
event: 'conf',
1387-
flags: this._enabledFlags | flag
1403+
flags: this._enabledFlags
13881404
})
1389-
1390-
return this._getEventPromise(this._getConfigEventKey(flag))
13911405
}
13921406

13931407
/**

test/lib/transports/ws2-unit.js

Lines changed: 136 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,59 @@ const createTestWSv2Instance = (params = {}) => {
1919
}
2020

2121
describe('WSv2 utilities', () => {
22+
it('sendEnabledFlags: sends the current flags value to the server', async () => {
23+
const ws = new WSv2()
24+
const wss = new MockWSv2Server()
25+
26+
await ws.open()
27+
28+
ws._enabledFlags = WSv2.flags.CHECKSUM
29+
ws.send = (packet) => {
30+
assert.strictEqual(packet.event, 'conf')
31+
assert.strictEqual(packet.flags, WSv2.flags.CHECKSUM)
32+
33+
wss.close()
34+
}
35+
36+
ws.sendEnabledFlags()
37+
})
38+
39+
it('enableFlag: saves enabled flag status', () => {
40+
const ws = new WSv2()
41+
42+
assert(!ws.isFlagEnabled(WSv2.flags.SEQ_ALL))
43+
assert(!ws.isFlagEnabled(WSv2.flags.CHECKSUM))
44+
45+
ws.enableFlag(WSv2.flags.SEQ_ALL)
46+
47+
assert(ws.isFlagEnabled(WSv2.flags.SEQ_ALL))
48+
assert(!ws.isFlagEnabled(WSv2.flags.CHECKSUM))
49+
50+
ws.enableFlag(WSv2.flags.CHECKSUM)
51+
52+
assert(ws.isFlagEnabled(WSv2.flags.SEQ_ALL))
53+
assert(ws.isFlagEnabled(WSv2.flags.CHECKSUM))
54+
})
55+
56+
it('enableFlag: sends conf packet if open', async () => {
57+
const ws = new WSv2()
58+
const wss = new MockWSv2Server()
59+
let confSent = false
60+
61+
await ws.open()
62+
63+
ws.send = (packet) => {
64+
assert(_isObject(packet))
65+
assert.strictEqual(packet.event, 'conf')
66+
confSent = true
67+
68+
wss.close()
69+
}
70+
71+
ws.enableFlag(WSv2.flags.SEQ_ALL)
72+
assert(confSent)
73+
})
74+
2275
it('_registerListener: correctly adds listener to internal map with cbGID', () => {
2376
const ws = new WSv2()
2477
ws._registerListener('trade', { 2: 'tBTCUSD' }, Map, 42, () => {})
@@ -45,12 +98,23 @@ describe('WSv2 utilities', () => {
4598

4699
it('enableSequencing: sends the correct conf flag', (done) => {
47100
const ws = new WSv2()
48-
ws.send = (packet) => {
49-
assert.strictEqual(packet.event, 'conf')
50-
assert.strictEqual(packet.flags, 65536)
51-
done()
52-
}
53-
ws.enableSequencing()
101+
const wss = new MockWSv2Server()
102+
103+
ws.once('open', () => {
104+
setTimeout(() => { // send is used by the open hander
105+
ws.send = (packet) => {
106+
assert.strictEqual(packet.event, 'conf')
107+
assert.strictEqual(packet.flags, 65536)
108+
109+
wss.close()
110+
done()
111+
}
112+
113+
ws.enableSequencing()
114+
}, 20)
115+
})
116+
117+
ws.open()
54118
})
55119

56120
it('getCandles: returns empty array if no candle set is available', () => {
@@ -121,27 +185,45 @@ describe('WSv2 lifetime', () => {
121185
assert.strictEqual(ws.isAuthenticated(), false)
122186
})
123187

124-
it('open: fails to open twice', (done) => {
188+
it('open: fails to open twice', async () => {
125189
const wss = new MockWSv2Server()
126190
const ws = createTestWSv2Instance()
127-
ws.on('open', () => {
128-
ws.open().then(() => assert(false)).catch(() => {
129-
wss.close()
130-
done()
131-
})
132-
})
133-
ws.open()
191+
192+
await ws.open()
193+
194+
try {
195+
await ws.open()
196+
assert(false)
197+
} catch (e) {
198+
wss.close()
199+
}
134200
})
135201

136-
it('open: updates open flag', (done) => {
202+
it('open: updates open flag', async () => {
137203
const wss = new MockWSv2Server()
138204
const ws = createTestWSv2Instance()
139-
ws.on('open', () => {
140-
assert.strictEqual(ws.isOpen(), true)
205+
206+
await ws.open()
207+
208+
assert.strictEqual(ws.isOpen(), true)
209+
wss.close()
210+
})
211+
212+
it('open: sends flags value', async () => {
213+
const wss = new MockWSv2Server()
214+
const ws = createTestWSv2Instance()
215+
let flagsSent = false
216+
217+
ws.enableSequencing()
218+
ws.sendEnabledFlags = () => {
219+
assert.strictEqual(ws._enabledFlags, WSv2.flags.SEQ_ALL)
220+
flagsSent = true
141221
wss.close()
142-
done()
143-
})
144-
ws.open()
222+
}
223+
224+
await ws.open()
225+
226+
assert(flagsSent)
145227
})
146228

147229
it('close: doesn\'t close if not open', (done) => {
@@ -164,24 +246,20 @@ describe('WSv2 lifetime', () => {
164246
})
165247
})
166248

167-
it('close: clears connection state', (done) => {
249+
it('close: clears connection state', async () => {
168250
const wss = new MockWSv2Server()
169251
const ws = createTestWSv2Instance()
170252
ws._onWSClose = () => {} // disable fallback reset
171253

172-
ws.open()
173-
ws.on('open', () => {
174-
assert(ws._ws !== null)
175-
assert(ws._isOpen)
254+
await ws.open()
255+
assert(ws._ws !== null)
256+
assert(ws._isOpen)
176257

177-
ws.close().then(() => {
178-
assert(ws._ws == null)
179-
assert(!ws._isOpen)
258+
await ws.close()
259+
assert(ws._ws == null)
260+
assert(!ws._isOpen)
180261

181-
wss.close()
182-
done()
183-
})
184-
})
262+
wss.close()
185263
})
186264

187265
it('auth: fails to auth twice', (done) => {
@@ -209,34 +287,38 @@ describe('WSv2 lifetime', () => {
209287
})
210288
})
211289

212-
it('auth: forwards calc param', (done) => {
290+
it('auth: forwards calc param', async () => {
213291
const wss = new MockWSv2Server()
214292
const ws = createTestWSv2Instance()
215-
ws.open()
216-
ws.on('open', () => {
217-
ws.send = (data) => {
218-
assert.strictEqual(data.calc, 42)
219-
wss.close()
220-
done()
221-
}
293+
let sentCalc = false
222294

223-
ws.auth(42)
224-
})
295+
await ws.open()
296+
297+
ws.send = (data) => {
298+
assert.strictEqual(data.calc, 42)
299+
wss.close()
300+
sentCalc = true
301+
}
302+
303+
ws.auth(42) // note promise ignored
304+
assert(sentCalc)
225305
})
226306

227-
it('auth: forwards dms param', (done) => {
307+
it('auth: forwards dms param', async () => {
228308
const wss = new MockWSv2Server()
229309
const ws = createTestWSv2Instance()
230-
ws.open()
231-
ws.on('open', () => {
232-
ws.send = (data) => {
233-
assert.strictEqual(data.dms, 42)
234-
wss.close()
235-
done()
236-
}
310+
let sentDMS = false
237311

238-
ws.auth(0, 42)
239-
})
312+
await ws.open()
313+
314+
ws.send = (data) => {
315+
assert.strictEqual(data.dms, 42)
316+
wss.close()
317+
sentDMS = true
318+
}
319+
320+
ws.auth(0, 42) // note promise ignored
321+
assert(sentDMS)
240322
})
241323

242324
it('reconnect: connects if not already connected', (done) => {
@@ -385,22 +467,12 @@ describe('WSv2 auto reconnect', () => {
385467
})
386468

387469
describe('WSv2 seq audit', () => {
388-
it('automatically enables sequencing if seqAudit is true in constructor', (done) => {
389-
const wss = new MockWSv2Server()
470+
it('automatically enables sequencing if seqAudit is true in constructor', () => {
390471
const ws = createTestWSv2Instance({
391472
seqAudit: true
392473
})
393474

394-
wss._onClientMessage = (ws, msgJSON) => {
395-
const msg = JSON.parse(msgJSON)
396-
397-
if (msg.event === 'conf' && msg.flags === 65536) {
398-
wss.close()
399-
done()
400-
}
401-
}
402-
403-
ws.open()
475+
assert(ws.isFlagEnabled(WSv2.flags.SEQ_ALL))
404476
})
405477

406478
it('emits error on invalid seq number', (done) => {

0 commit comments

Comments
 (0)