Skip to content

[AIT-207] Partial object sync#117

Open
lawrence-forooghian wants to merge 4 commits intoAIT-322-v6-ProtocolMessagefrom
AIT-207-partial-object-sync
Open

[AIT-207] Partial object sync#117
lawrence-forooghian wants to merge 4 commits intoAIT-322-v6-ProtocolMessagefrom
AIT-207-partial-object-sync

Conversation

@lawrence-forooghian
Copy link
Collaborator

@lawrence-forooghian lawrence-forooghian commented Feb 26, 2026

Note: This PR is based on top of #114; please review that one first.

Implements the following spec commits, which allow the server to split a large object over multiple OBJECT_SYNC messages.

See commit message for more details.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced robustness of object synchronization sequence handling with improved validation of object state transitions.
  • Tests

    • Expanded test coverage for OBJECT_SYNC sequences with support for multi-message synchronization, partial object updates, and unknown object type handling.

@lawrence-forooghian lawrence-forooghian changed the base branch from main to AIT-322-v6-ProtocolMessage February 26, 2026 13:42
@coderabbitai
Copy link

coderabbitai bot commented Feb 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: ac7a76a1-be6d-4a93-805f-1f9795fc4297

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

A refactoring replaces array-based sync object storage with a dedicated SyncObjectsPool type that manages partial sync message merging and accumulation. SyncObjectsPool validates, merges map entries, and handles counter states during OBJECT_SYNC sequences.

Changes

Cohort / File(s) Summary
Core Sync Pool Implementation
Sources/AblyLiveObjects/Internal/SyncObjectsPool.swift
New internal struct implementing Sequence protocol to accumulate and merge partial object sync data (RTO5f), with logic for map merging, tombstone handling, counter validation, and iterator support.
Sync Pool Integration
Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift, Sources/AblyLiveObjects/Internal/ObjectsPool.swift
Updated SyncSequence to use SyncObjectsPool instead of array. Modified nosync_applySyncObjectsPool to accept SyncObjectsPool and changed error handling from warning+nil to preconditionFailure for invalid states.
Removed Legacy Type
Sources/AblyLiveObjects/Internal/SyncObjectsPoolEntry.swift
Deleted internal struct SyncObjectsPoolEntry, replaced by SyncObjectsPool.Entry nested type.
Test Helpers & Infrastructure
Tests/AblyLiveObjectsTests/Helpers/TestFactories.swift, Tests/AblyLiveObjectsTests/ObjectsPoolTests.swift
Extended inboundObjectMessage factory with optional serialTimestamp parameter. Added testsOnly_fromStates helper to build SyncObjectsPool from state pairs for tests.
Test Coverage
Tests/AblyLiveObjectsTests/SyncObjectsPoolTests.swift, Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift
New comprehensive unit tests for SyncObjectsPool accumulation, merging, and iteration. Added integration tests validating multi-message OBJECT_SYNC sequences, partial map merges, and unknown object type handling.
Test Specifications
Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
Updated spec annotation from RTO5b to RTO5f in HandleObjectSyncProtocolMessageTests.

Sequence Diagram

sequenceDiagram
    participant Channel
    participant InternalDefaultRealtimeObjects
    participant SyncObjectsPool
    participant ObjectsPool
    
    Channel->>InternalDefaultRealtimeObjects: Receive OBJECT_SYNC message
    InternalDefaultRealtimeObjects->>SyncObjectsPool: accumulate(objectMessage)
    activate SyncObjectsPool
    Note over SyncObjectsPool: Validate state & object type<br/>Merge map entries / handle tombstone<br/>Store or update entry
    SyncObjectsPool-->>InternalDefaultRealtimeObjects: Pool updated
    deactivate SyncObjectsPool
    
    Channel->>InternalDefaultRealtimeObjects: Receive next OBJECT_SYNC (or end)
    InternalDefaultRealtimeObjects->>SyncObjectsPool: accumulate(objectMessage)
    activate SyncObjectsPool
    Note over SyncObjectsPool: Continue merging partial data
    SyncObjectsPool-->>InternalDefaultRealtimeObjects: Pool updated
    deactivate SyncObjectsPool
    
    InternalDefaultRealtimeObjects->>ObjectsPool: nosync_applySyncObjectsPool(pool)
    activate ObjectsPool
    loop For each entry in pool
        ObjectsPool->>ObjectsPool: Create/update object with merged state
    end
    ObjectsPool-->>InternalDefaultRealtimeObjects: Objects applied
    deactivate ObjectsPool
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐰 Pools of sync data merge and flow,
Partial messages now can grow,
Maps accumulate without a fuss,
Tombstones clear and entries gush,
Ably's objects dance on cue! 🌊

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 84.21% which is sufficient. The required threshold is 80.00%.
Title check ✅ Passed The PR title "AIT-207 Partial object sync" directly corresponds to the main objective, which is implementing partial object sync support (RTO5f) that allows servers to split large objects across multiple OBJECT_SYNC messages.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch AIT-207-partial-object-sync

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects February 26, 2026 13:43 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from cf6edee to a2a010e Compare February 26, 2026 14:07
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects February 26, 2026 14:09 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch 3 times, most recently from 7689879 to dadaade Compare March 4, 2026 11:56
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from a2a010e to 67a92dd Compare March 4, 2026 13:31
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 13:33 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch from dadaade to ee5b2f9 Compare March 4, 2026 13:34
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from 67a92dd to b900be3 Compare March 4, 2026 13:38
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 13:40 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch from ee5b2f9 to dff72b2 Compare March 4, 2026 14:30
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from b900be3 to e1438f6 Compare March 4, 2026 14:30
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 14:32 Inactive
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 14:32 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch 2 times, most recently from ffc512f to 02bfedb Compare March 4, 2026 16:19
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from e1438f6 to 1989994 Compare March 4, 2026 16:20
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 16:21 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch 2 times, most recently from 3a18180 to 7ec81af Compare March 4, 2026 18:55
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from 1989994 to 70d9862 Compare March 4, 2026 19:13
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 19:14 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch from 7ec81af to 65b36dc Compare March 4, 2026 19:17
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from 70d9862 to 183c690 Compare March 4, 2026 19:23
@lawrence-forooghian
Copy link
Collaborator Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 4, 2026 19:25 Inactive
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Sources/AblyLiveObjects/Internal/SyncObjectsPool.swift`:
- Line 1: This file currently only imports Foundation but must explicitly import
Ably and the internal plugin support module; update the top of
SyncObjectsPool.swift to add `import Ably` and an internal import for
`_AblyPluginSupportPrivate` (i.e., `@_internal import
_AblyPluginSupportPrivate`) so the non-test AblyLiveObjects sources have the
required module visibility for symbols used in this file.
- Around line 52-55: The code force-unwraps merged.object and mergedObject.map
during map merging which can crash if the stored entry for that objectId isn't a
map; change the logic in the merge path to safely unwrap and type-check before
accessing entries: use optional binding on merged.object and merged.object?.map
(or detect if merged.object is a non-map entry) and handle the mismatch by
either initializing a new map entry for merged (e.g., create a new map container
with empty entries) or skipping/overwriting safely instead of force-unwrapping;
update the references around merged.object, mergedObject.map, and
mergedMap.entries to use the safe optional values and fallbacks.

In `@Tests/AblyLiveObjectsTests/JS` Integration
Tests/ObjectsIntegrationTests.swift:
- Around line 736-967: Add the required spec attribution comments above each new
test case: for the "OBJECT_SYNC sequence builds object tree across multiple sync
messages" scenario, add the appropriate `@spec` or `@specPartial` comment
referencing the exact spec point; for "partial OBJECT_SYNC merges map entries
across multiple messages for the same objectId" add the `@specPartial` (since it’s
a partial-sync scenario) with the exact spec id; and for "OBJECT_SYNC does not
break when receiving an unknown object type" add the `@spec` comment with the
exact spec id. Place each attribution as a single-line comment immediately
before the .init(...) block (do not duplicate the same `@spec` for a spec already
attributed elsewhere) and use the exact comment format mandated by
CONTRIBUTING.md so the tests are traceable.

In `@Tests/AblyLiveObjectsTests/SyncObjectsPoolTests.swift`:
- Around line 1-3: The test file SyncObjectsPoolTests.swift is missing required
module imports; update the top of the file (where you currently have "@testable
import AblyLiveObjects", "import Foundation", "import Testing") to also import
Ably and _AblyPluginSupportPrivate by adding "import Ably" and "import
_AblyPluginSupportPrivate" so the tests can reference Ably types and plugin
support; keep `@testable` import AblyLiveObjects as-is and do not use an internal
import for _AblyPluginSupportPrivate.
- Line 95: In SyncObjectsPoolTests (the test class with the duplicate `@spec` tag
RTO5f2a2), locate the two occurrences of "@spec RTO5f2a2" and remove the
duplicate by converting one of them to the split-style tag required by
CONTRIBUTING.md (e.g., use "@specOneOf RTO5f2a2" or the appropriate
`@specPartial/`@specOneOf form per the guidelines), ensuring the exact comment
formatting matches the repository's spec-tag convention and that only one plain
"@spec RTO5f2a2" remains.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0502d5af-8a15-4698-8d80-2d11502f56ea

📥 Commits

Reviewing files that changed from the base of the PR and between 65b36dc and 183c690.

📒 Files selected for processing (9)
  • Sources/AblyLiveObjects/Internal/InternalDefaultRealtimeObjects.swift
  • Sources/AblyLiveObjects/Internal/ObjectsPool.swift
  • Sources/AblyLiveObjects/Internal/SyncObjectsPool.swift
  • Sources/AblyLiveObjects/Internal/SyncObjectsPoolEntry.swift
  • Tests/AblyLiveObjectsTests/Helpers/TestFactories.swift
  • Tests/AblyLiveObjectsTests/InternalDefaultRealtimeObjectsTests.swift
  • Tests/AblyLiveObjectsTests/JS Integration Tests/ObjectsIntegrationTests.swift
  • Tests/AblyLiveObjectsTests/ObjectsPoolTests.swift
  • Tests/AblyLiveObjectsTests/SyncObjectsPoolTests.swift
💤 Files with no reviewable changes (1)
  • Sources/AblyLiveObjects/Internal/SyncObjectsPoolEntry.swift

@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 5, 2026 11:59 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from 3d02fe7 to 18df1c8 Compare March 5, 2026 11:59
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 5, 2026 12:01 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from 18df1c8 to cbd73a9 Compare March 5, 2026 12:47
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 5, 2026 12:49 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-207-partial-object-sync branch from cbd73a9 to 00d0efc Compare March 5, 2026 13:15
@lawrence-forooghian lawrence-forooghian changed the title [WIP, AIT-207] Partial object sync [AIT-207] Partial object sync Mar 5, 2026
@lawrence-forooghian lawrence-forooghian marked this pull request as ready for review March 5, 2026 13:16
@github-actions github-actions bot temporarily deployed to staging/pull/117/AblyLiveObjects March 5, 2026 13:17 Inactive
@lawrence-forooghian lawrence-forooghian force-pushed the AIT-322-v6-ProtocolMessage branch 2 times, most recently from 15dfe04 to 2dcf9bb Compare March 9, 2026 16:48
lawrence-forooghian and others added 4 commits March 9, 2026 13:52
Will be useful for some upcoming tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Give the sync objects pool its own type instead of using a bare
[SyncObjectsPoolEntry] array. This makes the concept explicit and is
preparation for implementing partial object sync, which will expand the
capabilities of this type.

I wouldn't pay too much attention to the tests; they'll be replaced
soon.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port the two integration tests added in ably-js commit b20d3ed:

- OBJECT_SYNC sequence builds object tree across multiple sync messages
- OBJECT_SYNC does not break when receiving an unknown object type

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements the changes from spec commits 1f22417, 9f4d7de, and 963ec30,
which allow the server to split a large object across multiple
OBJECT_SYNC protocol messages.

The new integration test is ported from ably-js commit d0bc431.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant