Skip to content

Commit f57632f

Browse files
committed
[AIT-276] feat: enhance object operation handling and test coverage
- Improved handling of skipped operations on ACK (RTO9a3) with detailed comments on echo discard logic. - Added extensive unit tests for `ObjectsManager`, `LiveMapManager`, and `DefaultLiveCounter` covering edge cases like buffering, tombstoning, and operation deduplication. - Introduced helper properties for buffered ACKs and object operations in tests.
1 parent 08fd014 commit f57632f

File tree

7 files changed

+751
-2
lines changed

7 files changed

+751
-2
lines changed

liveobjects/src/main/kotlin/io/ably/lib/objects/ObjectsManager.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,14 @@ internal class ObjectsManager(private val realtimeObjects: DefaultRealtimeObject
223223
continue
224224
}
225225

226-
// RTO9a3 - skip operations already applied on ACK
226+
// RTO9a3 - skip operations already applied on ACK (discard without taking any further action).
227+
// This check comes before zero-value object creation (RTO9a2a1) so that no zero-value object is
228+
// created for an objectId not yet in the pool when the echo is being discarded.
229+
// Note: siteTimeserials is NOT updated here intentionally — updating it to the echo's serial would
230+
// incorrectly reject older-but-unprocessed operations from the same site that arrive after the echo.
227231
if (objectMessage.serial != null &&
228232
realtimeObjects.appliedOnAckSerials.contains(objectMessage.serial)) {
229-
Log.d(tag, "RTO9a3: serial ${objectMessage.serial} already applied on ACK; discarding")
233+
Log.d(tag, "RTO9a3: serial ${objectMessage.serial} already applied on ACK; discarding echo")
230234
realtimeObjects.appliedOnAckSerials.remove(objectMessage.serial)
231235
continue // discard without taking any further action
232236
}

liveobjects/src/test/kotlin/io/ably/lib/objects/unit/TestHelpers.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ internal val ObjectsManager.SyncObjectsDataPool: Map<String, ObjectState>
7373
internal val ObjectsManager.BufferedObjectOperations: List<ObjectMessage>
7474
get() = this.getPrivateField("bufferedObjectOperations")
7575

76+
internal val ObjectsManager.BufferedAcks: List<Pair<List<ObjectMessage>, *>>
77+
get() = this.getPrivateField("bufferedAcks")
78+
7679
internal var DefaultRealtimeObjects.ObjectsManager: ObjectsManager
7780
get() = this.getPrivateField("objectsManager")
7881
set(value) = this.setPrivateField("objectsManager", value)

0 commit comments

Comments
 (0)