Skip to content

Commit 1fa3eeb

Browse files
committed
BatchContext and batch API on PathObject and Instance
1 parent 38ab803 commit 1fa3eeb

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

textile/objects-features.textile

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,14 @@ A @PathObject@ is obtained from @RealtimeObject#get@ ("RTO23":#RTO23), which ret
893893
*** @(RTPO21a1)@ @options@ @PathObjectSubscriptionOptions@ (optional) - same options as @PathObject#subscribe@ ("RTPO19b":#RTPO19b)
894894
** @(RTPO21b)@ Returns a stream or iterable that yields @PathObjectSubscriptionEvent@ objects, using the idiomatic construct for the language (e.g. async iterators, channels, flows, or async sequences)
895895
** @(RTPO21c)@ Internally wraps @PathObject#subscribe@ ("RTPO19":#RTPO19), converting the callback-based subscription into the appropriate streaming or iterable pattern
896+
* @(RTPO22)@ @PathObject#batch@ function:
897+
** @(RTPO22a)@ Expects a synchronous function @fn@ that receives a @BatchContext@ as its argument
898+
** @(RTPO22b)@ Requires the @OBJECT_PUBLISH@ channel mode to be granted per "RTO2":#RTO2
899+
** @(RTPO22c)@ Resolves the path to a @LiveObject@ using the internal path resolution procedure. If the path does not resolve to a @LiveObject@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
900+
** @(RTPO22d)@ Creates a @RootBatchContext@ ("RTBC16":#RTBC16) wrapping the resolved @Instance@
901+
** @(RTPO22e)@ Executes @fn@, passing the @BatchContext@ as argument
902+
** @(RTPO22f)@ After @fn@ returns, flushes the @RootBatchContext@ ("RTBC16d":#RTBC16d) to publish all queued operations atomically
903+
** @(RTPO22g)@ The @RootBatchContext@ is closed after flush completes, regardless of success or failure
896904

897905
h3(#instance). Instance
898906

@@ -967,6 +975,84 @@ An @Instance@ holds a direct reference to a specific resolved @LiveObject@ or pr
967975
** @(RTINS18a)@ If the wrapped value is not a @LiveObject@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
968976
** @(RTINS18b)@ Returns a stream or iterable that yields @InstanceSubscriptionEvent@ objects, using the idiomatic construct for the language (e.g. async iterators, channels, flows, or async sequences)
969977
** @(RTINS18c)@ Internally wraps @Instance#subscribe@ ("RTINS16":#RTINS16), converting the callback-based subscription into the appropriate streaming or iterable pattern
978+
* @(RTINS19)@ @Instance#batch@ function:
979+
** @(RTINS19a)@ Expects a synchronous function @fn@ that receives a @BatchContext@ as its argument
980+
** @(RTINS19b)@ Requires the @OBJECT_PUBLISH@ channel mode to be granted per "RTO2":#RTO2
981+
** @(RTINS19c)@ If the wrapped value is not a @LiveObject@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
982+
** @(RTINS19d)@ Creates a @RootBatchContext@ ("RTBC16":#RTBC16) wrapping this @Instance@
983+
** @(RTINS19e)@ Executes @fn@, passing the @BatchContext@ as argument
984+
** @(RTINS19f)@ After @fn@ returns, flushes the @RootBatchContext@ ("RTBC16d":#RTBC16d) to publish all queued operations atomically
985+
** @(RTINS19g)@ The @RootBatchContext@ is closed after flush completes, regardless of success or failure
986+
987+
h3(#batchcontext). BatchContext
988+
989+
A @BatchContext@ wraps an @Instance@ with synchronous write methods that queue operations instead of sending them immediately. All queued operations are published atomically as a single channel message when the batch function returns. This allows multiple mutations to be grouped into a single publish call.
990+
991+
* @(RTBC1)@ The @BatchContext@ class provides a synchronous write interface for grouping multiple mutations into a single atomic publish
992+
** @(RTBC1a)@ A specific SDK implementation may choose to expose a subset of the methods available on the @BatchContext@ class based on the known underlying type, in a similar manner to @Instance@ ("RTINS1a":#RTINS1a)
993+
* @(RTBC2)@ @BatchContext@ has the following internal properties:
994+
** @(RTBC2a)@ @instance@ - the underlying @Instance@ that this @BatchContext@ wraps
995+
** @(RTBC2b)@ @rootContext@ - a reference to the @RootBatchContext@ ("RTBC16":#RTBC16) that manages the batch operation
996+
* @(RTBC3)@ @BatchContext#id@ property:
997+
** @(RTBC3a)@ Returns the @objectId@ of the underlying @Instance@ ("RTINS3":#RTINS3)
998+
** @(RTBC3b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000, indicating that the batch is closed
999+
* @(RTBC4)@ @BatchContext#get@ function:
1000+
** @(RTBC4a)@ Expects a @key@ @String@ argument
1001+
** @(RTBC4b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1002+
** @(RTBC4c)@ Delegates to @Instance#get@ ("RTINS5":#RTINS5) on the underlying @Instance@. If the result is undefined, returns undefined
1003+
** @(RTBC4d)@ Otherwise, wraps the resulting @Instance@ in a @BatchContext@ via the @RootBatchContext#wrapInstance@ ("RTBC16c":#RTBC16c) and returns it
1004+
* @(RTBC5)@ @BatchContext#value@ function:
1005+
** @(RTBC5a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1006+
** @(RTBC5b)@ Delegates to @Instance#value@ ("RTINS4":#RTINS4) on the underlying @Instance@
1007+
* @(RTBC6)@ @BatchContext#entries@ function:
1008+
** @(RTBC6a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1009+
** @(RTBC6b)@ Delegates to @Instance#entries@ ("RTINS6":#RTINS6) on the underlying @Instance@, wrapping each yielded @Instance@ value in a @BatchContext@ via @RootBatchContext#wrapInstance@ ("RTBC16c":#RTBC16c)
1010+
** @(RTBC6c)@ Yields @[String, BatchContext]@ pairs
1011+
* @(RTBC7)@ @BatchContext#keys@ function:
1012+
** @(RTBC7a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1013+
** @(RTBC7b)@ Delegates to @Instance#keys@ ("RTINS7":#RTINS7) on the underlying @Instance@
1014+
* @(RTBC8)@ @BatchContext#values@ function:
1015+
** @(RTBC8a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1016+
** @(RTBC8b)@ Delegates to @Instance#values@ ("RTINS8":#RTINS8) on the underlying @Instance@, wrapping each yielded @Instance@ in a @BatchContext@ via @RootBatchContext#wrapInstance@ ("RTBC16c":#RTBC16c)
1017+
* @(RTBC9)@ @BatchContext#size@ function:
1018+
** @(RTBC9a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1019+
** @(RTBC9b)@ Delegates to @Instance#size@ ("RTINS9":#RTINS9) on the underlying @Instance@
1020+
* @(RTBC10)@ @BatchContext#compact@ function:
1021+
** @(RTBC10a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1022+
** @(RTBC10b)@ Delegates to @Instance#compact@ ("RTINS10":#RTINS10) on the underlying @Instance@
1023+
* @(RTBC11)@ @BatchContext#compactJson@ function:
1024+
** @(RTBC11a)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1025+
** @(RTBC11b)@ Delegates to @Instance#compactJson@ ("RTINS11":#RTINS11) on the underlying @Instance@
1026+
* @(RTBC12)@ @BatchContext#set@ function. This method is synchronous:
1027+
** @(RTBC12a)@ Expects the following arguments:
1028+
*** @(RTBC12a1)@ @key@ @String@ - the key to set the value for
1029+
*** @(RTBC12a2)@ @value@ @Boolean | Binary | Number | String | JsonArray | JsonObject | LiveCounterValueType | LiveMapValueType@ - the value to assign to the key
1030+
** @(RTBC12b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1031+
** @(RTBC12c)@ If the wrapped value is not a @LiveMap@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
1032+
** @(RTBC12d)@ Queues a message constructor on the @RootBatchContext@ that, when executed, creates @ObjectMessages@ for a @MAP_SET@ operation in the same manner as @LiveMap#set@ ("RTLM20e":#RTLM20e)
1033+
* @(RTBC13)@ @BatchContext#remove@ function. This method is synchronous:
1034+
** @(RTBC13a)@ Expects a @key@ @String@ argument
1035+
** @(RTBC13b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1036+
** @(RTBC13c)@ If the wrapped value is not a @LiveMap@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
1037+
** @(RTBC13d)@ Queues a message constructor on the @RootBatchContext@ that, when executed, creates an @ObjectMessage@ for a @MAP_REMOVE@ operation in the same manner as @LiveMap#remove@ ("RTLM21e":#RTLM21e)
1038+
* @(RTBC14)@ @BatchContext#increment@ function. This method is synchronous:
1039+
** @(RTBC14a)@ Expects the following arguments:
1040+
*** @(RTBC14a1)@ @amount@ @Number@ (optional) - the amount by which to increment the counter value. Defaults to 1
1041+
** @(RTBC14b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1042+
** @(RTBC14c)@ If the wrapped value is not a @LiveCounter@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
1043+
** @(RTBC14d)@ Queues a message constructor on the @RootBatchContext@ that, when executed, creates an @ObjectMessage@ for a @COUNTER_INC@ operation in the same manner as @LiveCounter#increment@ ("RTLC12":#RTLC12)
1044+
* @(RTBC15)@ @BatchContext#decrement@ function. This method is synchronous:
1045+
** @(RTBC15a)@ Expects the following arguments:
1046+
*** @(RTBC15a1)@ @amount@ @Number@ (optional) - the amount by which to decrement the counter value. Defaults to 1
1047+
** @(RTBC15b)@ If the batch is closed, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000
1048+
** @(RTBC15c)@ If the wrapped value is not a @LiveCounter@, the library must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 92007
1049+
** @(RTBC15d)@ Delegates to @BatchContext#increment@ ("RTBC14":#RTBC14) with the negated @amount@
1050+
* @(RTBC16)@ Internal @RootBatchContext@ - manages the lifecycle and message queue for a batch operation:
1051+
** @(RTBC16a)@ Maintains an internal @wrappedInstances@ map that memoizes @BatchContext@ wrappers by @objectId@
1052+
** @(RTBC16b)@ Maintains an internal @queuedMessageConstructors@ list of deferred message constructor functions. Some @ObjectMessages@ require asynchronous I/O during construction (e.g. generating an @objectId@ for nested value types), so message constructors are queued during synchronous batch method calls and executed on flush
1053+
** @(RTBC16c)@ @wrapInstance@ function: wraps an @Instance@ in a @BatchContext@. If the @Instance@ has an @objectId@ and a wrapper for that @objectId@ already exists in @wrappedInstances@, the existing wrapper is returned. Otherwise, a new @BatchContext@ is created and stored in @wrappedInstances@
1054+
** @(RTBC16d)@ @flush@ function: closes the batch context, executes all queued message constructors, flattens the resulting @ObjectMessages@ into a single array, and publishes them using @RealtimeObject#publish@ ("RTO15":#RTO15). If there are no queued messages, no publish is performed
1055+
** @(RTBC16e)@ After the batch is closed, any method call on the @BatchContext@ or its children must throw an @ErrorInfo@ error with @statusCode@ 400 and @code@ 40000, indicating that the batch is closed
9701056

9711057
h2(#idl). Interface Definition
9721058

@@ -1070,6 +1156,7 @@ class PathObject: // RTPO*
10701156
subscribe((PathObjectSubscriptionEvent) -> listener, PathObjectSubscriptionOptions? options) -> Subscription // RTPO19
10711157
unsubscribe((PathObjectSubscriptionEvent) -> listener) // RTPO20
10721158
subscribeIterator(PathObjectSubscriptionOptions? options) -> Stream<PathObjectSubscriptionEvent> // RTPO21
1159+
batch(((BatchContext) ->) fn) => io // RTPO22
10731160

10741161
class Instance: // RTINS*
10751162
id: String? // RTINS3
@@ -1088,4 +1175,20 @@ class Instance: // RTINS*
10881175
subscribe((InstanceSubscriptionEvent) -> listener) -> Subscription // RTINS16
10891176
unsubscribe((InstanceSubscriptionEvent) -> listener) // RTINS17
10901177
subscribeIterator() -> Stream<InstanceSubscriptionEvent> // RTINS18
1178+
batch(((BatchContext) ->) fn) => io // RTINS19
1179+
1180+
class BatchContext: // RTBC*
1181+
id: String? // RTBC3
1182+
get(String key) -> BatchContext? // RTBC4
1183+
value() -> (Boolean | Binary | Number | String | JsonArray | JsonObject)? // RTBC5
1184+
entries() -> Iterator<[String, BatchContext]> // RTBC6
1185+
keys() -> Iterator<String> // RTBC7
1186+
values() -> Iterator<BatchContext> // RTBC8
1187+
size() -> Number? // RTBC9
1188+
compact() -> Object? // RTBC10
1189+
compactJson() -> Object? // RTBC11
1190+
set(String key, (Boolean | Binary | Number | String | JsonArray | JsonObject | LiveCounterValueType | LiveMapValueType) value) // RTBC12
1191+
remove(String key) // RTBC13
1192+
increment(Number amount?) // RTBC14
1193+
decrement(Number amount?) // RTBC15
10911194
</pre>

0 commit comments

Comments
 (0)