Skip to content

Multi-tab Electric: a committed row disappears after tabs stop #2283

Open

Description

@KyleAMathews

Summary

The multi-tab Electric oracle found a history where a durable row disappears. Two tabs share one persisted database. After a tab stops and the other tab catches up and stops, durable storage and both tabs lack row 1. The model expects row 1 with label v2.

The oracle and the behavior that it checks came in with #2265. The failure reproduces on main at 6bf0e86. The random campaign draws a new seed for each run, so CI fails on this history only intermittently. #2263 passed CI because its run drew a different seed.

Law

A server change that a tab applied and committed stays in durable storage and in every tab after all tabs catch up. A tab stop does not remove committed rows.

Counterexample

Oracle: packages/browser-db-sqlite-persistence/tests/multi-tab-electric-oracle.test.ts, test keeps reserved commits lawful across generated multi-tab histories (random or replayed), property browser.multi-tab-reserved-history.

Counterexample: [{"tabCount":2,"steps":[
  {"kind":"server change","key":1,"pick":0},
  {"kind":"catch up","tab":0,"pick":0},
  {"kind":"server change","key":1,"pick":0},
  {"kind":"catch up","tab":0,"pick":0},
  {"kind":"catch up","tab":1,"pick":1},
  {"kind":"catch up","tab":0,"pick":0},
  {"kind":"stop","tab":1,"pick":0},
  {"kind":"catch up","tab":0,"pick":0},
  {"kind":"stop","tab":0,"pick":0}]}]

Observation after every tab caught up:

actual   {"durableRows":[{"id":2,"label":"two"}],
          "tabs":[{"tab":"A","status":"ready","rows":[{"id":2,"label":"two"}]},
                  {"tab":"B","status":"ready","rows":[{"id":2,"label":"two"}]}]}
expected {"durableRows":[{"id":1,"label":"v2"},{"id":2,"label":"two"}],
          "tabs":[{"tab":"A","status":"ready","rows":[{"id":1,"label":"v2"},{"id":2,"label":"two"}]},
                  {"tab":"B","status":"ready","rows":[{"id":1,"label":"v2"},{"id":2,"label":"two"}]}]}

Replay

Run this in packages/browser-db-sqlite-persistence:

TANSTACK_DB_ORACLE_PROPERTY=browser.multi-tab-reserved-history \
TANSTACK_DB_ORACLE_SEED=-1660880085 \
TANSTACK_DB_ORACLE_PATH="55:0:1:4:4:4:1:1:1:1:3:4:4:4:4" \
npx vitest run tests/multi-tab-electric-oracle.test.ts -t "random or replayed"

Related

Next steps

  • Diagnose which step removes row 1: the second tab's catch-up with pick: 1, the stop of tab B, or the last catch-up of tab A.
  • Record the trace in docs/contributing/oracle-coverage.md under the multi-tab Electric owner until a fix lands.
  • Fix oracle-first: keep this history as a replay, show RED on the parent, GREEN after the fix, and a hostile mutant that fails.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions