stdb: connect({ protocol = "v2" }), opt-in #84
No reviewers
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!84
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "bsatn-phase3-integration"
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?
Phase 3 of #9. Stacked on #83. This is the PR that makes v2 reachable.
v1 stays the default and its value surface is frozen. v2 negotiates the BSATN subprotocol, pins
compression=Noneand sends binary frames. The cache grows exactly one decoder seam,cache.row_decoder, so a single apply path serves both wires.The eight v2 handlers reuse the v1 effects rather than forking the event surface —
credentials,subscription_settledandsubscription_errorare now shared by both handler tables. Event-table rows are the one new event type and are never cached.Where the wires genuinely differ, v1 wins:
SubscriptionErrordrops no rows. Only the server knows which of them another live query set still matches.(err, msg)shape (#38), soret_valuestays raw BSATN.updatesentry per query set per table, because the cache's hold counts depend on that.Also worth knowing:
on_out_of_energycan never fire on v2 — the v2 outcome has noOutOfEnergyvariant, so exhaustion arrives asInternalErrortext.Verified: 10 passed, 0 failed on this branch alone.
test_connection.luadrives binary frames end to end and asserts the v1/v2 cache dumps and event sequences are identical. 7 mutants injected across the init/cache seams; all 7 killed.0d9bcfbe9a6a47e5487eReview round: v1 confirmed unchanged, four correctness fixes, two untested guards now tested
The thing this PR most needed to prove
v1 behaviour is independently confirmed UNCHANGED. The pre-patch v1 suites pass verbatim
against the new source — not adapted, not re-baselined. For a change that adds a second protocol
through shared seams (
decode_rows,handle_frame, the pending registry), that is the finding thatmatters, and it is the one a reader of this diff cannot check by eye.
Fixed
inside the write pass, after that batch's deletes had already been committed — so the cache was
left half-applied and the callback was never settled, which is worse than either failure alone. The
check moved into the pure pass; the offending relation is now skipped and reported, the same way
every other undecodable relation already degrades.
escaped with the request already half-registered.
light = falsewas rejected — while the docstring callsfalsethe default. Passing thedocumented default explicitly was an error.
Errhanded the frozen callback four length bytes and an embedded NUL instead of theerror text. The frozen v1.0 callback surface is exactly where a raw-bytes leak must not happen.
Tests
Two guards whose own comments call them load-bearing had no test. They now do. A comment asserting
that a guard matters is a claim; the test is what keeps it true.
Verification state at the stack tip (
bsatn-phase5-docs): unit suite 11 passed, 0 failed;all four conformance suites PASS end to end — v1 native, v2 native, v1 HTML5, v2 HTML5 — under the
new protocol-specific gates, whose negative controls were proven non-vacuous;
stylua --check stdb dev/testclean.
6a47e5487e6e36f0ddd36e36f0ddd34002f9f18b