Skip to content
This repository has been archived by the owner on Apr 14, 2023. It is now read-only.

Feature: inactivity timeout and tests #390

Merged
merged 3 commits into from
Apr 19, 2018
Merged

Feature: inactivity timeout and tests #390

merged 3 commits into from
Apr 19, 2018

Conversation

divyenduz
Copy link
Contributor

@divyenduz divyenduz commented Apr 4, 2018

TODO:

  • Make sure all of the significant new logic is covered by tests
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass
  • Update CHANGELOG.md with your change

@divyenduz
Copy link
Contributor Author

Fixes #351

@timsuchanek
Copy link
Contributor

Yeah! This is really cool! Looks good to me!
Is this good to merge @NeoPhi ?

@NeoPhi NeoPhi requested a review from mxstbr April 9, 2018 13:54
src/client.ts Outdated
@@ -167,6 +174,9 @@ export class SubscriptionClient {

let opId: string;

this.activeSubscriptions += 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be next to where this.operations[opId] = is done to ensure the reference counting it done correctly. Or possibly the check should just be against Object.keys(this.operations).length to avoid needing to do reference counting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, we are not counting activeSubscriptions anymore and relying on Object.keys(this.operations).length to test inactivity.

}
}

private setInactivityTimeout() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What should the behavior of this function be as it related to lazy = false since unsubscribe is the only place it gets called.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this function also test for connection to exist? I think this function is idempotent as is and can be called in any state. Not sure on the impact of lazy flag on this? Can you please elaborate.

src/client.ts Outdated
if (this.inactivityTimeout > 0 && this.activeSubscriptions === 0) {
this.inactivityTimeoutId = setTimeout(() => {
if (this.activeSubscriptions === 0) {
this.close();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add a test to verify that if the connection is closed due to inactivity, a future subscribe will correctly reopen the connection.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, added the relevant test case.

@@ -352,6 +362,23 @@ export class SubscriptionClient {
}
}

private clearInactivityTimeout() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a call to this if the connection is closed for any other reason, otherwise I could see the reconnect logic fighting with the inactivity timeout and possibly tripping the flags for closedByUser.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, if a connection is closed (say, manually) but inactivity timeout had started. It might close the connection after reconnection.

To get around this, I called clearInactivityTimeout inside the close function.

Based on the feedback on the PR, this commit does the following:-

1. Rely on `Object.keys(this.operations).length` to detect inactivity in place of manually counting active subscriptions.

2. Call `clearInactivityTimeout` on connection close to handle the case when connection is closed for another reason than inactivity timeout, it should not mess with reconnect logic and other related operations.

3. Add test case to validate that reconnection on subscribe works after a connection was closed due to inactivity.
@divyenduz
Copy link
Contributor Author

@NeoPhi : Thanks for the feedback

  1. Updated the code to rely on Object.keys(this.operations).length instead of manually counting the references.

  2. Called clearInactivityTimeout on close to avoid it messing up with reconnect logic.

  3. Added the test case to check reconnection after connection was closed due to inactivity.

Please let me know if any further changes are needed.

@timsuchanek
Copy link
Contributor

@NeoPhi any news on this? Sorry for bothering, but we really need this to be merged as all people using server-side subscriptions with Yoga have connection leaks right now.

@NeoPhi
Copy link
Contributor

NeoPhi commented Apr 19, 2018

@timsuchanek I would contend that if a well behaved client is causing memory leaks in Yoga, that sounds like a server side issue. Long lived idle WebSockets are fine.

baconz pushed a commit to PhiloInc/subscriptions-transport-ws that referenced this pull request Apr 24, 2018
timsuchanek pushed a commit to prisma-labs/prisma-binding that referenced this pull request May 4, 2018
* Add inactivityTimeout option to subscription client

1. Passed through websocket link
2. Requires bump in version after this is merged apollographql/subscriptions-transport-ws#390

* bump version of subscriptions-transport-ws to 0.9.8
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants