[AIT-286] Fix rules for buffering of incoming object operations during LiveObjects sync#416
[AIT-286] Fix rules for buffering of incoming object operations during LiveObjects sync#416
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes the BufferedObjectOperations clearing behavior for LiveObjects synchronization by ensuring operations are cleared at the correct time based on when the server caches object state.
Changes:
- Added RTO4d to specify that BufferedObjectOperations must be cleared when ATTACHED is received without the RESUMED flag, since the server caches object state at channel attachment time
- Added RTO5f as an explanatory note describing the expected and edge-case behaviors for server-initiated resyncs
- Deleted RTO5a2b which previously required clearing BufferedObjectOperations when a new sync sequence ID arrived
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Needed for implementing RTO4d from [1]. [1] ably/specification#416
Needed for implementing RTO4d from [1]. [1] ably/specification#416
Needed for implementing RTO4d from [1]. [1] ably/specification#416
Needed for implementing RTO4d from [1]. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. All written by Claude. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. All written by Claude. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. All written by Claude. [1] ably/specification#416
That is, do it when we get a discontinuity, not when a new sync sequence changes, per spec changes in [1]. Integration tests ported from JS in [2] at 06b746a. All written by Claude. [1] ably/specification#416 [2] ably/ably-js#2150
Let's have a DR?In general, the spec usually describes the "what" and not the "why". When it does explain the "why", it usually:
I think that we'd benefit from having a short DR explaining the motivation behind this new behaviour. I think that the two things it should describe are:
Why it would be an error to apply buffered operations after a discontinuityConsider the case where the client ends up reconnecting to some different region It's thus possible that there exists some operation This diagram, showing the events from the point of view of a Realtime client, might explain it better; assume that all of the blue messages are from the same region, and that there exists another earlier message |
That is, do it when we get a discontinuity, not when a new sync sequence starts, per spec changes in [1]. Integration tests ported from JS in [2] at 06b746a. All written by Claude. [1] ably/specification#416 [2] ably/ably-js#2150
textile/objects-features.textile
Outdated
| *** @(RTO5a2)@ If a new sequence id is sent from Ably, the client library must treat it as the start of a new objects sync sequence, and any previous in-flight sync must be discarded: | ||
| **** @(RTO5a2a)@ The @SyncObjectsPool@ list must be cleared | ||
| **** @(RTO5a2b)@ The @BufferedObjectOperations@ list must be cleared | ||
| **** @(RTO5a2b)@ This clause has been deleted |
There was a problem hiding this comment.
I'd say replaced, not deleted
There was a problem hiding this comment.
updated to say it was replaced by RTO4d
69b2a65 to
9efcfb1
Compare
Done both. Also note: our SDK implementations also had a separate bug where LiveObjects sync handling was only triggered for non-RESUMED ATTACHED messages (fixed in ably-js in ably/ably-js#2150). This is not a spec issue - RTO4 has never conditioned on RESUMED and has always applied to every ATTACHED message. This was purely an implementation bug, likely also present in the Kotlin and Swift plugins. |
Buffered object operations must be cleared on every ATTACHED message, not when a new OBJECT_SYNC sequence starts. If HAS_OBJECTS flag is set, the realtime server will deliver a sync sequence following the ATTACHED, guaranteeing that the objects in that sequence include at least all operations up to the point of attachment. If HAS_OBJECTS is not set, the client performs an implicit sync sequence (emitting SYNCING then immediately clearing local state). For server-initiated resync, the server is expected to send an ATTACHED message before the new OBJECT_SYNC sequence. However, if an OBJECT_SYNC is received after a completed sync without a preceding ATTACHED, the client handles this on a best-effort basis by buffering operations from that point. Since the buffer is cleared at sync completion, this works implicitly. Read more in the the DR [1] Resolves AIT-286 [1] https://ably.atlassian.net/wiki/x/NQAEHgE
9efcfb1 to
48d604d
Compare
Buffered object operations must be cleared on every ATTACHED message,
not when a new OBJECT_SYNC sequence starts.
If HAS_OBJECTS flag is set, the realtime server will deliver a sync
sequence following the ATTACHED, guaranteeing that the objects in that
sequence include at least all operations up to the point of attachment.
If HAS_OBJECTS is not set, the client performs an implicit sync sequence
(emitting SYNCING then immediately clearing local state).
For server-initiated resync, the server is expected to send an ATTACHED
message before the new OBJECT_SYNC sequence. However, if an OBJECT_SYNC
is received after a completed sync without a preceding ATTACHED, the
client handles this on a best-effort basis by buffering operations from
that point. Since the buffer is cleared at sync completion, this works
implicitly.
Resolves AIT-286
See ably-js implementation ably/ably-js#2150