Skip to content

Commit 71b4d17

Browse files
authored
fix: LiveQueryClient.resubscribe with Parse Server 7 causes many open connections (#2184)
1 parent 23a3ded commit 71b4d17

File tree

4 files changed

+43
-7
lines changed

4 files changed

+43
-7
lines changed

integration/test/ParseLiveQueryTest.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,35 @@ describe('Parse LiveQuery', () => {
9090
await promise;
9191
});
9292

93+
it('can resubscribe', async () => {
94+
const client = new Parse.LiveQueryClient({
95+
applicationId: 'integration',
96+
serverURL: 'ws://localhost:1337',
97+
javascriptKey: null,
98+
masterKey: null,
99+
sessionToken: null,
100+
});
101+
client.open();
102+
const resubscribeSpy = spyOn(client, 'resubscribe').and.callThrough();
103+
const subscribeRequest = {
104+
op: 'subscribe',
105+
requestId: 1,
106+
query: {
107+
className: 'TestObject',
108+
where: { objectId: 'HEXkuHFm0D' },
109+
keys: ['foo', 'objectId'],
110+
watch: undefined,
111+
unknownField: 'throws Additional properties not allowed error',
112+
},
113+
sessionToken: undefined,
114+
};
115+
await client.connectPromise;
116+
client.socket.send(JSON.stringify(subscribeRequest));
117+
await sleep(1000);
118+
expect(resubscribeSpy).toHaveBeenCalled();
119+
await client.close();
120+
});
121+
93122
it('can subscribe to multiple queries', async () => {
94123
const objectA = new TestObject();
95124
const objectB = new TestObject();

integration/test/helper.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ jasmine.getEnv().addReporter(new SpecReporter());
55

66
const ParseServer = require('parse-server').default;
77
const CustomAuth = require('./CustomAuth');
8-
const sleep = require('./sleep');
98
const { TestUtils } = require('parse-server');
109
const Parse = require('../../node');
1110
const fs = require('fs');

src/LiveQueryClient.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ const SUBSCRIPTION_EMMITER_TYPES = {
5555
DELETE: 'delete',
5656
};
5757

58+
// Exponentially-growing random delay
5859
const generateInterval = k => {
5960
return Math.random() * Math.min(30, Math.pow(2, k) - 1) * 1000;
6061
};
@@ -291,7 +292,8 @@ class LiveQueryClient {
291292
const query = subscription.query;
292293
const queryJSON = query.toJSON();
293294
const where = queryJSON.where;
294-
const fields = queryJSON.keys ? queryJSON.keys.split(',') : undefined;
295+
const keys = queryJSON.keys?.split(',');
296+
const watch = queryJSON.watch?.split(',');
295297
const className = query.className;
296298
const sessionToken = subscription.sessionToken;
297299
const subscribeRequest = {
@@ -300,7 +302,8 @@ class LiveQueryClient {
300302
query: {
301303
className,
302304
where,
303-
fields,
305+
keys,
306+
watch,
304307
},
305308
sessionToken: undefined as string | undefined,
306309
};
@@ -347,7 +350,6 @@ class LiveQueryClient {
347350
}
348351

349352
_handleWebSocketOpen() {
350-
this.attempts = 1;
351353
const connectRequest = {
352354
op: OP_TYPES.CONNECT,
353355
applicationId: this.applicationId,
@@ -387,6 +389,7 @@ class LiveQueryClient {
387389
break;
388390
case OP_EVENTS.SUBSCRIBED:
389391
if (subscription) {
392+
this.attempts = 1;
390393
subscription.subscribed = true;
391394
subscription.subscribePromise.resolve();
392395
setTimeout(() => subscription.emit(SUBSCRIPTION_EMMITER_TYPES.OPEN, response), 200);
@@ -485,19 +488,16 @@ class LiveQueryClient {
485488
if (this.state === CLIENT_STATE.DISCONNECTED) {
486489
return;
487490
}
488-
489491
this.state = CLIENT_STATE.RECONNECTING;
490492
const time = generateInterval(this.attempts);
491493

492494
// handle case when both close/error occur at frequent rates we ensure we do not reconnect unnecessarily.
493495
// we're unable to distinguish different between close/error when we're unable to reconnect therefore
494496
// we try to reconnect in both cases
495497
// server side ws and browser WebSocket behave differently in when close/error get triggered
496-
497498
if (this.reconnectHandle) {
498499
clearTimeout(this.reconnectHandle);
499500
}
500-
501501
this.reconnectHandle = setTimeout(
502502
(() => {
503503
this.attempts++;

src/__tests__/LiveQueryClient-test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,8 @@ describe('LiveQueryClient', () => {
944944
};
945945
const query = new ParseQuery('Test');
946946
query.equalTo('key', 'value');
947+
query.select(['key']);
948+
query.watch(['key']);
947949
liveQueryClient.subscribe(query);
948950
liveQueryClient.connectPromise.resolve();
949951

@@ -961,6 +963,8 @@ describe('LiveQueryClient', () => {
961963
where: {
962964
key: 'value',
963965
},
966+
keys: ['key'],
967+
watch: ['key'],
964968
},
965969
});
966970
});
@@ -978,6 +982,8 @@ describe('LiveQueryClient', () => {
978982
};
979983
const query = new ParseQuery('Test');
980984
query.equalTo('key', 'value');
985+
query.select(['key']);
986+
query.watch(['key']);
981987
liveQueryClient.subscribe(query, 'mySessionToken');
982988
liveQueryClient.connectPromise.resolve();
983989

@@ -996,6 +1002,8 @@ describe('LiveQueryClient', () => {
9961002
where: {
9971003
key: 'value',
9981004
},
1005+
keys: ['key'],
1006+
watch: ['key'],
9991007
},
10001008
});
10011009
});

0 commit comments

Comments
 (0)