Handles for subscriptions and reducer calls #29
Labels
No labels
area:defold
area:docs
area:infra
area:protocol
area:testing
kind:bug
kind:chore
phase:breadth
phase:core
phase:hardening
phase:slice
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
yuris/spacetimedb-defold#29
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two async operations return a bare
query_idorrequest_idand take a single(err, ...)callback. Both peer SDKs return an object instead, and the difference shows up in ordinary code.Subscriptions
subscribe_queryreturns aquery_idyou hold and later pass tounsubscribe. There is no way to ask whether it is still live, and the applied and error paths both arrive through the one callback.The Godot SDK returns a handle with
query_id,applied/endsignals,active/endedstate,wait_for_applied(timeout)andunsubscribe(). The official Rust SDK has the same state machine (Pending → Sent → Applied → Ended/Error) withis_active()/is_ended().The concretely awkward case today: after a reconnect, query sets are replayed under their original
query_id, so a handle stays valid — but a subscription that errored is dropped, and the holder has no way to discover that except by having caught the callback at the time. State on the handle makes it observable.Reducer calls
call_reducer(name, args, cb)gives one callback with(err, update). The wire distinguishes more:Committed,Failed(message)andOutOfEnergy.stdb/connection.lua:301-321already separates all three internally, then flattens them to a single error string before the consumer sees it.OutOfEnergyis not the same class of problem as a reducer that threw — one is the account's fault, the other the module's — and a game may well want to surface them differently. Collapsing both into a string loses that distinction.Shape
Constraints:
reducer_call_timeoutand leaves it unimplemented, which is a fair warning: pending calls currently live until the connection drops. A timeout needs a real owner in the update loop and a defined interaction with reconnect replay. Prefer shipping handles without timeouts over shipping half a timeout.awaitfree from engine signals; the Lua equivalent is a coroutine wrapper, which is a separate opinion and a separate issue.Acceptance
Unit tests: handle state transitions including the error path,
unsubscribeon an already-ended subscription being a no-op rather than an error, each of the three reducer outcomes reaching its own callback, and the legacy callback form behaving exactly as it does today.