Disconnection and reconnection logic in client SDKs
Clients can lose connection to the server for a variety of reasons. We need to deal with this behavior in client SDKs. Things we may want:
- Log in console when connection is lost.
- Add hooks to let users add custom behavior when connection is lost.
- Possibly perform some sort of reconciliation with old state when the server sends over all the new state.
- Alternatively, let the client tell the server "i got everything up to here" and server fills in the rest. This seems expensive, but it means clients don't need to worry about reconciliation, everything just goes through the on-update logic they already coded.
- Auto-reconnect logic with exponential backoff (on by default?)
Client SDKs:
- [x] Rust
- [ ] C#/Unity
- [ ] Typescript ~- [ ] Python~ - Python is deprecated (John)
Add hooks to let users add custom behavior when connection is lost.
The Rust SDK allows custom behavior on disconnecting as of #235 .
Possibly perform some sort of reconciliation with old state when the server sends over all the new state.
I don't know that reconciliation is necessary. The client cache can't have diverged from the server (because it can't be mutated directly); it will always be a consistent prefix. When the client re-connects and re-subscribes, their cache will be populated via subscribe normally, which should be all the reconciliation we need. The client won't see intermediate states or reducer events, but I don't see any plausible way to change that while remaining performant.
Auto-reconnect logic with exponential backoff, on by default.
I'm somewhat skeptical of auto-reconnect as a "default" behavior in the sense of being enabled unless the client opts out. IMO, we should take a similar approach as we do to saving credentials to disk: offer a convenient way for client authors to opt in to the behavior, and encourage them to do so in the quickstarts and references.
I don't know that reconciliation is necessary. The client cache can't have diverged from the server (because it can't be mutated directly); it will always be a consistent prefix. When the client re-connects and re-subscribes, their cache will be populated via subscribe normally, which should be all the reconciliation we need. The client won't see intermediate states or reducer events, but I don't see any plausible way to change that while remaining performant.
That makes sense. I was mainly wondering if the client is going to see the entire client cache deleted and then re-added on reconnect.
I was mainly wondering if the client is going to see the entire client cache deleted and then re-added on reconnect.
Hmm, this is something for which we'll need to nail down the semantics. Should row delete callbacks be called when you disconnect (unclear)? Should the client cache be cleared upon disconnecting (probably not; this breaks cloud-next)? What about on reconnecting (unclear; in Rust, currently it is cleared, but delete callbacks are not invoked)? Should a new subscription after re-connecting behave like a re-subscribe, i.e. should it avoid invoking insert callbacks for already-resident rows?
Yeah, exactly. I think avoiding insert callbacks is nice for game devs -- especially if they're driving heavy operations like Unity scene manipulation. But it wants careful design.
I'm happy to do the client implementation on this, although I think @RReverser and @lcodes are up to speed on this code as well.
Closing in favor of the various Stable API tickets