Skip to content

Commit

Permalink
feat(client): Add lazyCloseTimeout as a close timeout after last op…
Browse files Browse the repository at this point in the history
…eration completes

Closes enisdenjo#17
  • Loading branch information
enisdenjo committed Mar 9, 2022
1 parent 79d0266 commit 16e5e31
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 2 deletions.
17 changes: 17 additions & 0 deletions docs/interfaces/ClientOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [fetchFn](ClientOptions.md#fetchfn)
- [headers](ClientOptions.md#headers)
- [lazy](ClientOptions.md#lazy)
- [lazyCloseTimeout](ClientOptions.md#lazyclosetimeout)
- [retryAttempts](ClientOptions.md#retryattempts)
- [singleConnection](ClientOptions.md#singleconnection)
- [url](ClientOptions.md#url)
Expand Down Expand Up @@ -96,6 +97,22 @@ in "distinct connection mode" (`singleConnection = false`).

___

### lazyCloseTimeout

`Optional` **lazyCloseTimeout**: `number`

How long should the client wait before closing the connection after the last oparation has
completed. You might want to have a calmdown time before actually closing the connection.

Meant to be used in combination with `lazy`.

Note that the `lazy` option has NO EFFECT when using the client
in "distinct connection mode" (`singleConnection = false`).

**`default`** 0

___

### retryAttempts

`Optional` **retryAttempts**: `number`
Expand Down
29 changes: 29 additions & 0 deletions src/__tests__/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ describe('single connection mode', () => {

const client = createClient({
singleConnection: true,
lazy: true, // default
url,
fetchFn: fetch,
retryAttempts: 0,
Expand Down Expand Up @@ -203,6 +204,34 @@ describe('single connection mode', () => {
await waitForComplete();
await waitForDisconnect();
});

it('should disconnect after the lazyCloseTimeout has passed after last unsubscribe', async () => {
const { url, waitForOperation, waitForDisconnect } = await startTServer();

const client = createClient({
singleConnection: true,
lazy: true, // default
lazyCloseTimeout: 20,
url,
fetchFn: fetch,
retryAttempts: 0,
});

const sub = tsubscribe(client, {
query: 'subscription { ping }',
});
await waitForOperation();

sub.dispose();

await sub.waitForComplete();

// still connected due to timeout
await waitForDisconnect(() => fail("Shouldn't have disconnected"), 10);

// but will disconnect after timeout
await waitForDisconnect();
});
});

describe('non-lazy', () => {
Expand Down
29 changes: 27 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ export interface ClientOptions {
* @default true
*/
lazy?: boolean;
/**
* How long should the client wait before closing the connection after the last oparation has
* completed. You might want to have a calmdown time before actually closing the connection.
*
* Meant to be used in combination with `lazy`.
*
* Note that the `lazy` option has NO EFFECT when using the client
* in "distinct connection mode" (`singleConnection = false`).
*
* @default 0
*/
lazyCloseTimeout?: number;
/**
* Used ONLY when the client is in non-lazy mode (`lazy = false`). When
* using this mode, errors might have no sinks to report to; however,
Expand Down Expand Up @@ -178,6 +190,7 @@ export function createClient(options: ClientOptions): Client {
const {
singleConnection = false,
lazy = true,
lazyCloseTimeout = 0,
onNonLazyError = console.error,
/**
* Generates a v4 UUID to be used as the ID using `Math`
Expand Down Expand Up @@ -511,8 +524,20 @@ export function createClient(options: ClientOptions): Client {
// try again
retryingErr = err;
} finally {
// release lock if aborted, and disconnect if no more locks
if (control.signal.aborted && --locks === 0) connCtrl.abort();
// release lock if subscription is aborted
if (control.signal.aborted && --locks === 0) {
if (isFinite(lazyCloseTimeout) && lazyCloseTimeout > 0) {
// allow for the specified calmdown time and then close the
// connection, only if no lock got created in the meantime and
// if the connection is still open
setTimeout(() => {
if (!locks) connCtrl.abort();
}, lazyCloseTimeout);
} else {
// otherwise close immediately
connCtrl.abort();
}
}
}
}
})()
Expand Down

0 comments on commit 16e5e31

Please sign in to comment.