-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Eagerly start subscription heartbeats #7871
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…ng-running setup steps before returning its async generator
✅ Deploy Preview for apollo-server-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
trevor-scheer
approved these changes
Apr 18, 2024
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
Merged
tninesling
pushed a commit
that referenced
this pull request
Apr 18, 2024
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. # Releases ## @apollo/server-integration-testsuite@4.10.4 ### Patch Changes - Updated dependencies \[[`18a3827`](18a3827)]: - @apollo/server@4.10.4 ## @apollo/server@4.10.4 ### Patch Changes - [#7871](#7871) [`18a3827`](18a3827) Thanks [@tninesling](https://github.com/tninesling)! - Subscription heartbeats are initialized prior to awaiting subscribe(). This allows long-running setup to happen in the returned Promise without the subscription being terminated prior to resolution. Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
Eagerly start subscription heartbeats in case the subscription has long-running setup steps before returning its async generator. When a subscription is configured,
subscribe
can return either anAsyncGenerator
or aPromise<AsyncGenerator>
. If anAsyncGenerator
is returned, the previous code works fine. We get the generator right away and set up the heartbeat to keep things alive, even if the generator has long-running setup code before returning values.On the other hand, if the
Promise<AsyncGenerator>
takes longer than the hearbeat interval to resolve, the router will terminate the subscription. When the subscription actually starts generating data, the callback returns 404, as it has already been cleaned up. We want the system to gracefully wait for the setup code to complete, since we will do so if the setup code is placed inside the iterator itself.Example
In this example,
subscribe
returns aPromise<AsyncGenerator>
, but thePromise
resolves quickly. This results in the heartbeat being started prior to the long-running setup. The heartbeat keeps the subscription alive until the setup is completed, then it can start sending data to the client.On the other hand, waiting for the setup before resolving the
Promise
leads to complications.Solution
This change eagerly starts the heartbeat interval prior to awaiting the returned value from
subscribe
. This allows long-running setup code to run concurrently with the heartbeats. Previously the second example would result in aSUBSCRIPTION_HEARTBEAT_ERROR
and subscription termination. Now, the router receives heartbeats so it correctly waits for the setup and data in both cases.