apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.28k stars 2.64k forks source link

RFC: Reconciliation query for subscription disconnect/reconnect #1639

Closed thebigredgeek closed 5 years ago

thebigredgeek commented 7 years ago

Motivation

As it stands, there is not currently a well-defined method for reconciling subscribed data in disconnect -> reconnect scenarios via WebSocket transport. With any real time system, there must be a way to tolerate connection issues. By not providing a pattern for this with subscribeToMore, we are leaving a huge question open in the mind of any seasoned engineer who has worked on real time applications. This likely carves off a large percentage of apollo-client's conversion funnel when it comes to building real time applications for fear of Apollo Client not yet being "mature enough".

Proposed Solution

I think it would be really useful to provide the end user with a “reconcile” query option for subscriptions. The reconcile query would fire any time the websocket connection is lost and then reconnected. The purpose of the reconcile query would be to fetch any missed messages that may have been published during the connectivity outage.

There are two different ways that I can see this working:

1) Re-run the existing query with it’s last set of options/variables, optionally overriding them if desired. This forces an implicit assumption that the original query is declarative enough to handle fetch missing data without additional front-end side effects.

2) Specify an additional query document and attach it to the configuration of subscribeToMore. In many cases, this could be the exact same document as the original query that is being subscribed to. When the connection is lost and then recovered, this query fires allowing the server to compensate, perhaps by using a cursor to the last known record from the subscription as an offset.

Implementation / Next steps

1) Nail down the desired API @helfer @stubailo 2) TBH

helfer commented 7 years ago

@thebigredgeek I think that's an interesting idea. I think we built something similar for our Galaxy UI.

The main problem I see is that even running such a query will give you no guarantees about consistency, because the subscription events might not be in sync with the query result, so you still have to figure out what changes to apply and what changes to skip. That being said, maybe we shouldn't let the perfect be the enemy of the good.

thebigredgeek commented 7 years ago

@helfer agreed, there is additional complexity. I think the main goal for a v1 fix should be to simply provide the user a means to handle this. Building a query that accurately reconciles is the onus of the user, not apollo-client. I think a bit of functional code within update queries fixes duplicate messages, etc. I don't think you need strong guarantees around pulling exactly the messages that are needed. I think the messages needed + some extras are fine, if that is what you mean.

jaridmargolin commented 7 years ago

The reconcile query would fire any time the websocket connection is lost and then reconnected

Unfortunately there is no guarantee that the websocket disconnect was reported.

I don't know quite enough about the Apollo client, or if any of the ideas will carry over, but the team at Layer had a few interesting ideas utilizing a counter: https://docs.layer.com/reference/client_api/websocket_recovery


Hopefully you don't mind me crashing your conversation. I've been surfing the webz all night looking for inspiration on how to solve this issue reliably :)

stale[bot] commented 6 years ago

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

thebigredgeek commented 6 years ago

@jaridmargolin you could probably implement some sort of ping/pong (I think this already exists) and pass a last-message user-specific nonce with each pass. That way, if the server sends a nonce that is > last nonce + 1, we know we had a connection issue.

stale[bot] commented 6 years ago

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

scf4 commented 6 years ago

@thebigredgeek @jaridmargolin are you guys any further along with a solution for this?

stale[bot] commented 6 years ago

This issue has been automatically marked as stale becuase it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions to Apollo Client!

stubailo commented 6 years ago

ping - we incorrectly configured stalebot, it shouldn't close discussion issues.

hwillson commented 5 years ago

To help provide a more clear separation between feature requests / discussions and bugs, and to help clean up the feature request / discussion backlog, Apollo Client feature requests / discussions are now being managed under the https://github.com/apollographql/apollo-feature-requests repository.

This feature request / discussion will be closed here, but anyone interested in migrating this issue to the new repository (to make sure it stays active), can click here to start the migration process. This manual migration process is intended to help identify which of the older feature requests are still considered to be of value to the community. Thanks!