Skip to content

Commit

Permalink
fix(client): Subscription can be disposed only once
Browse files Browse the repository at this point in the history
  • Loading branch information
enisdenjo committed Apr 28, 2021
1 parent 9103123 commit abd9c28
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/client.ts
Expand Up @@ -609,7 +609,6 @@ export function createClient(options: ClientOptions): Client {
);

releaser = () => {
locks--;
if (!completed && socket.readyState === WebSocketImpl.OPEN)
// if not completed already and socket is open, send complete message to server on release
socket.send(
Expand All @@ -618,6 +617,8 @@ export function createClient(options: ClientOptions): Client {
type: MessageType.Complete,
}),
);
locks--;
completed = true;
release();
};

Expand All @@ -635,7 +636,10 @@ export function createClient(options: ClientOptions): Client {
.catch(sink.error) // rejects on close events and errors
.then(sink.complete); // resolves on release or normal closure

return () => releaser();
return () => {
// allow disposing only if not already completed
if (!completed) releaser();
};
},
async dispose() {
disposed = true;
Expand Down
34 changes: 34 additions & 0 deletions src/tests/client.ts
Expand Up @@ -754,6 +754,40 @@ describe('lazy', () => {
client.close();
});
});

it('should not close connection if a subscription is disposed multiple times', async () => {
const { url, ...server } = await startTServer();

const client = createClient({
url,
lazy: true,
retryAttempts: 0,
});

// create 2 subscriptions
const sub0 = tsubscribe(client, {
query: 'subscription { ping(key: "0") }',
});
await server.waitForOperation();

const sub1 = tsubscribe(client, {
query: 'subscription { ping(key: "1") }',
});
await server.waitForOperation();

// dispose of the 2nd subscription 2 times (try decrementing locks twice)
sub1.dispose();
sub1.dispose();

// first subscription shouldnt complete and the client shouldnt disconnect
await sub0.waitForComplete(() => {
fail("subscription shouldn't have completed");
}, 20);

await server.waitForClientClose(() => {
fail("client shouldn't have closed");
}, 20);
});
});

describe('reconnecting', () => {
Expand Down

0 comments on commit abd9c28

Please sign in to comment.