Skip to content

Commit 32e2351

Browse files
lawrence-forooghianclaude
authored andcommitted
Add placeholder RTLO3f for parentReferences
Stubs out the new `parentReferences` internal property on `LiveObject`, needed by `getFullPaths` (RTLO4f). The detailed maintenance rules (across `MAP_SET`, `MAP_REMOVE`, `MAP_CLEAR`, `LiveMap` tombstoning, and post-sync rebuild) are deferred to a follow-up by Sachin; the in-progress draft is at [1]. ably-js stores `parentReferences` as a map keyed by a direct `LiveMap` reference; the placeholder instead keys by `objectId`, for consistency with how the rest of the LiveObjects spec models inter-object references (forward references in `LiveMap` entries are already objectIds resolved via the `ObjectsPool` on demand). This is also load-bearing for languages without automatic cycle collection. The protocol allows cyclic `LiveMap` graphs (e.g. `A.x = B`, `B.y = A`), and `getFullPaths` is being specified to handle them; under ARC in Swift, direct parent references in such a cycle would form an unbreakable retain cycle on the two `LiveMap`s. Keying by `objectId` lets the `ObjectsPool` remain the single owner and sidesteps the issue. Implementations remain explicitly permitted to store a direct `LiveMap` reference if more idiomatic in their language -- e.g. to avoid an `ObjectsPool` lookup at each `getFullPaths` traversal step -- as ably-js does today, provided they handle the cycle concern. [1] #480 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 294b7b1 commit 32e2351

1 file changed

Lines changed: 4 additions & 0 deletions

File tree

specifications/objects-features.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,9 @@ Objects feature enables clients to store shared data as "objects" on a channel.
323323
- `(RTLO3d1)` Set to `false` when the `LiveObject` is initialized
324324
- `(RTLO3e)` protected `tombstonedAt` (optional) Time - a timestamp indicating when this object was tombstoned. This property is nullable, and specification points that manipulate this value maintain the invariant that it is non-null if and only if `isTombstone` is `true`
325325
- `(RTLO3e1)` Set to undefined/null when the `LiveObject` is initialized
326+
- `(RTLO3f)` protected `parentReferences` `Dict<String, Set<String>>` - tracks which `LiveMap`s in the local `ObjectsPool` currently reference this `LiveObject`, and at which keys they do so. The mapping is keyed by the parent `LiveMap`'s `objectId`, with each value being the set of keys at which that `LiveMap` references this `LiveObject`. Used by `getFullPaths` ([RTLO4f](#RTLO4f)) to determine every path the object currently occupies in the LiveObjects tree
327+
- `(RTLO3f1)` This mapping is keyed by `objectId` for consistency with the rest of the LiveObjects spec, where references between objects are stored as `objectId`s and resolved via the `ObjectsPool` on demand. Implementations may store a direct reference to the parent `LiveMap` instead — for example to avoid an `ObjectsPool` lookup at each step of `getFullPaths` ([RTLO4f](#RTLO4f)) traversal — provided the observable behaviour is unchanged. Such implementations should be aware that this may introduce reference cycles between `LiveMap`s, and must ensure this does not cause memory leaks
328+
- `(RTLO3f2)` TODO: The detailed maintenance rules for `parentReferences` (across `MAP_SET`, `MAP_REMOVE`, `MAP_CLEAR`, `LiveMap` tombstoning, and post-sync rebuild) are to be specified by Sachin in a follow-up; see https://github.com/ably/specification/pull/480 for the in-progress draft
326329
- `(RTLO4)` `LiveObject` methods:
327330
- `(RTLO4b)` `subscribe` - subscribes a user to data updates on this `LiveObject` instance
328331
- `(RTLO4b1)` Requires the `OBJECT_SUBSCRIBE` channel mode to be granted per [RTO2](#RTO2)
@@ -1080,6 +1083,7 @@ Types and their properties/methods are public and exposed to users by default. A
10801083
createOperationIsMerged: Boolean // RTLO3c
10811084
isTombstone: Boolean // RTLO3d
10821085
tombstonedAt: Time? // RTLO3e
1086+
parentReferences: Dict<String, Set<String>> // RTLO3f
10831087
canApplyOperation(ObjectMessage) -> Boolean // RTLO4a
10841088
tombstone(ObjectMessage) // RTLO4e
10851089
subscribe((LiveObjectUpdate) ->) -> Subscription // RTLO4b

0 commit comments

Comments
 (0)