-
Notifications
You must be signed in to change notification settings - Fork 3
[PUB-1829] Add object-level write API spec for RealtimeObjects #353
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
e60fdf2 to
2553181
Compare
2553181 to
baee12a
Compare
There isn't a spec PR for this yet, but it's needed in order to implement the write spec [1]. Asked about it in [2]. It's implemented in JS in [3]. Got Cursor to do this. [1] ably/specification#353 [2] https://github.com/ably/specification/pull/353/files#r2228017382 [3] ably/ably-js#2065
| ** @(RTO11b)@ The return type is a @LiveMap@, which is returned once the required I/O has successfully completed | ||
| ** @(RTO11c)@ Requires the @OBJECT_PUBLISH@ channel mode to be granted per "RTO2":#RTO2 | ||
| ** @(RTO11d)@ If the channel is in the @DETACHED@, @FAILED@ or @SUSPENDED@ state, the library should throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 90001 | ||
| ** @(RTO11e)@ If "@echoMessages@":../features#TO3h client option is @false@, the library should throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000, indicating that @echoMessages@ must be enabled for this operation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the connection can be shared across PubSub, Chat, and Objects, echoMessages might limit the ability to do so. We need to assess the potential impact across various product offerings
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened a separate issue for this #365, and this can be discussed in future LiveObjects plugin discussions.
As of now, LiveObjects does not support applying operations locally first and instead relies on receiving echoed operations.
| *** @(RTO11f5)@ Create an initial value JSON string as described in "RTO13":#RTO13, passing in the partial @ObjectOperation@ from "RTO11f4":#RTO11f4 | ||
| *** @(RTO11f6)@ Create a unique nonce as a random string | ||
| *** @(RTO11f7)@ Get the current server time as described in "RTO16":#RTO16 | ||
| *** @(RTO11f8)@ Create an @objectId@ for the new @LiveMap@ object as described in "RTO14":#RTO14, passing in @map@ string as the @type@, the initial value JSON string from "RTO11f5":#RTO11f5, the nonce from "RTO11f6":#RTO11f6, and the server time from "RTO11f7":#RTO11f7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of REST APIs, objectId is optional and is automatically generated by the server.
Applying the same approach for realtime could reduce round-trip time for getting current server time —something particularly valuable when customers are using RealtimeObjects.
Although we're using the local offset to save round-trip time for subsequent requests, there's still a risk that the local clock may drift out of sync.
So, we can keep objectId generation optional in realtime as well, wdyt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Clock Drift Happens
- Hardware limitations: Even in modern servers, clock crystals have a natural drift—often ±20 parts per million (ppm) or better—leading to seconds or even minutes of drift over long periods if completely unsynchronized.
- Virtualization effects: Virtual machines (VMs) are affected by host clock changes, hypervisor scheduling, and pausing (such as during suspension or migration). This can lead to sudden jumps or drift in the OS-reported time.
- Synchronization interruptions: Network Time Protocol (NTP), Precision Time Protocol (PTP), and cloud-provider time sync services are used to keep clocks accurate. Any network issue, misconfiguration, or system trouble that prevents time sync can allow drift to accumulate, sometimes rapidly.
- System events: Actions such as rebooting, resuming from suspension, or falling back to OS instead of the hardware clock can cause higher drift or a temporary loss of sync
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Realtime, developers can obtain a reference to an object before the corresponding *_CREATE operation has been processed by the server and an ID has been generated for it. In such cases, it is crucial that the Realtime client is still able to send mutation operations for that object or reference it within other collection types. Without knowing the object ID, this becomes impossible and would require implementing a queuing mechanism, which would quickly become complex and difficult to manage.
The need for client-generated object IDs is further emphasized by the new path-based API and the proposed object creation changes here. Object creation is no longer an async method but instead a simple call like LiveCounter.create(), which returns a value type describing the structure of the object.
Furthermore, the end goal of the LiveObjects plugin is to provide a local-first, offline-first API, where changes can be made entirely offline on the client side and later synced via Realtime across all other clients. This is only possible if the client is able to generate object IDs.
For the REST API, all of the above is not relevant, so we can rely on the server to generate object IDs.
There isn't a spec PR for this yet, but it's needed in order to implement the write spec [1]. Asked about it in [2]. It's implemented in JS in [3]. Got Cursor to do this. [1] ably/specification#353 [2] https://github.com/ably/specification/pull/353/files#r2228017382 [3] ably/ably-js#2065
There isn't a spec PR for this yet, but it's needed in order to implement the write spec [1]. Asked about it in [2]. It's implemented in JS in [3]. Got Cursor to do this. [1] ably/specification#353 [2] https://github.com/ably/specification/pull/353/files#r2228017382 [3] ably/ably-js#2065
haven't done mode checking of RTLC12b Based on [1] at cb11ba8. TODO add support for JSON values here and in create — noticed that this snuck in [1] ably/specification#353
haven't done mode checking of RTLC12b Based on [1] at cb11ba8. TODO add support for JSON values here and in create — noticed that this snuck in [1] ably/specification#353
haven't done mode checking of RTLC12b Based on [1] at cb11ba8. TODO add support for JSON values here and in create — noticed that this snuck in [1] ably/specification#353
We need a type that represents (when considering [1] at cb11ba8) RTO13's "partial ObjectOperation"; namely an ObjectOperation without an objectId property. This is something that is easy to represent in TypeScript but a bit of a faff in Swift; we have to create a new type for it. Code largely generated by Cursor at my instruction. [1] ably/specification#353
Based on [1] at cb11ba8. Implementation deferred to #47. [1] ably/specification#353
haven't done mode checking of RTLC12b Based on [1] at cb11ba8. [1] ably/specification#353
We need a type that represents (when considering [1] at cb11ba8) RTO13's "partial ObjectOperation"; namely an ObjectOperation without an objectId property. This is something that is easy to represent in TypeScript but a bit of a faff in Swift; we have to create a new type for it. Code largely generated by Cursor at my instruction. [1] ably/specification#353
Based on [1] at cb11ba8. Implementation deferred to #47. [1] ably/specification#353
Based on [1] at cb11ba8. Internal interfaces by me, implementation and tests by Cursor (both with some tweaking by me). TODO tests for createCounter — copy from map TODO Unit tests for find-or-create (TODO what) Haven't implemented: - the RTO11e etc echoMessages check — deferred to #49 - the RTO11c etc channel mode checking - same reason as 392fae3 - using server time for generating object ID — deferred to #50 [1] ably/specification#353
Based on [1] at cb11ba8. Code by me, tests by Cursor and tidied up by me. Channel mode checking and echoMessages check omitted as in e65643a. [1] ably/specification#353
Based on [1] at cb11ba8. Internal interfaces by me, implementation and tests by Cursor (both with some tweaking by me). Haven't implemented: - the RTO11e etc echoMessages check — deferred to #49 - the RTO11c etc channel mode checking - same reason as 392fae3 - using server time for generating object ID — deferred to #50 [1] ably/specification#353
Based on [1] at cb11ba8. Code by me, tests by Cursor and tidied up by me. Channel mode checking and echoMessages check omitted as in e65643a. [1] ably/specification#353
Based on [1] at cb11ba8. Internal interfaces by me, implementation and tests by Cursor (both with some tweaking by me). Haven't implemented: - the RTO11e etc echoMessages check — deferred to #49 - the RTO11c etc channel mode checking - same reason as 392fae3 - using server time for generating object ID — deferred to #50 [1] ably/specification#353
Based on [1] at cb11ba8. Code by me, tests by Cursor and tidied up by me. Channel mode checking and echoMessages check omitted as in e65643a. [1] ably/specification#353
Based on [1] at cb11ba8. Internal interfaces by me, implementation and tests by Cursor (both with some tweaking by me). Haven't implemented: - the RTO11e etc echoMessages check — deferred to #49 - the RTO11c etc channel mode checking - same reason as 392fae3 - using server time for generating object ID — deferred to #50 [1] ably/specification#353
Based on [1] at cb11ba8. Code by me, tests by Cursor and tidied up by me. Channel mode checking and echoMessages check omitted as in e65643a. [1] ably/specification#353
Based on [1] at cb11ba8. Internal interfaces by me, implementation and tests by Cursor (both with some tweaking by me). Haven't implemented: - the RTO11e etc echoMessages check — deferred to #49 - the RTO11c etc channel mode checking - same reason as 392fae3 - using server time for generating object ID — deferred to #50 [1] ably/specification#353
Based on [1] at cb11ba8. Code by me, tests by Cursor and tidied up by me. Channel mode checking and echoMessages check omitted as in e65643a. [1] ably/specification#353
| *** @(RTO11f7)@ Get the current server time as described in "RTO16":#RTO16 | ||
| *** @(RTO11f8)@ Create an @objectId@ for the new @LiveMap@ object as described in "RTO14":#RTO14, passing in @map@ string as the @type@, the initial value JSON string from "RTO11f5":#RTO11f5, the nonce from "RTO11f6":#RTO11f6, and the server time from "RTO11f7":#RTO11f7 | ||
| *** @(RTO11f9)@ Set @ObjectMessage.operation.action@ to @ObjectOperationAction.MAP_CREATE@ | ||
| *** @(RTO11f10)@ Set @ObjectMessage.operation.objectId@ to the @objectId@ created in "RTO11f8":#RTO11f8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can make RTO11f10, RTO11f11.. etc as subpoints of RTO11f9, since we are constructing ObjectMessage for MapCreateOperation right
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the current structure is correct. The parent RTO11f specifies that an ObjectMessage for a MAP_CREATE action can be created by following its sub-items. You then simply follow these sub-items in sequence to construct the correct ObjectMessage.
It makes sense for RTO11f10 and the following items to be at the same level as RTO11f9 and the other RTO11f* entries, as they all describe the steps required to create the ObjectMessage.
a1c9a6a to
7149569
Compare
ffed7d7 to
79ad8d9
Compare
sacOO7
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
7149569 to
b696a9b
Compare
Adds spec for: - `RealtimeObjects.createMap` - `RealtimeObjects.createCounter` Resolves PUB-1829
Adds spec for: - `LiveCounter.increment` - `LiveCounter.decrement` - `LiveMap.set` - `LiveMap.remove` Resolves PUB-1829
79ad8d9 to
3517453
Compare
Adds spec for:
RealtimeObjects.createMapRealtimeObjects.createCounterRelated DRs: LLODR-027: OBJECT_ID semantic preserving client-side generated IDs (Object ID generation), LODR-018: High level write API overview
Resolves PUB-1829