Skip to content

zero-swift: client and storage fixes from the bug sweep - #13

Merged
tmm merged 5 commits into
mainfrom
swift-client-fixes
Oct 22, 2026
Merged

tmm merged 5 commits into
mainfrom
swift-client-fixes

Conversation

@tmm

@tmm tmm commented Oct 22, 2026

Copy link
Copy Markdown
Member

Fixes bugs found by the bug sweep. Each expected behavior was established from JS, and each test fails without its fix.

  • Empty poke: zero-cache sends a no-op poke on every new connection. Swift returned early and never marked got queries authoritative, so after a reconnect or relaunch with no server changes, views stayed .cached and run(.complete) / preload.complete hung. It now marks them, behind the same socket guard as JS.
  • NaN: <= and >= filters no longer match NaN. compare is unchanged, since sorting needs a total order.
  • Storage:
    • A write failure reaches every client sharing the database (a listener per client), not whichever registered last.
    • After a failed write, writes already queued on the SQLite queue are dropped.
    • SQLITE_BUSY/LOCKED is retried by the next write, not treated as a storage failure (JS classifySQLiteError).
    • A read failure loading the client group moves the client to memory and is reported through onStorageFailure, as an open failure is.
    • The memory fallback is shared by name within the process, like .memory.

Also keeps the sweep's seeded IVM fuzz generator and its curated cases.

Checked: 191 Swift tests, swift format lint --strict, and ClientE2ETests against a real zero-cache.

ampagent and others added 5 commits October 22, 2026 02:05
…itative

As in zero.ts, the poke callback marks the got queries authoritative after rep.poke, even when the poke is a no-op, if the socket it came on is still the current one. An empty first poke after a reconnect or relaunch left views and preloads incomplete.

Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859
Co-authored-by: tmm <tmm@tmm.dev>
JS compareValues returns a - b, which is NaN for a NaN operand, so <= and >= are false. compare keeps its total order for sorting.

Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859
Co-authored-by: tmm <tmm@tmm.dev>
…are retried

- Every client sharing a ReplicaDatabase hears about a write failure; a closed client is removed.
- SQLiteStore stops writing at the first failure, so writes queued before it don't land after it.
- SQLITE_BUSY/LOCKED is not a storage failure (classifySQLiteError): the ops are kept and written with the next write.
- A read failure loading the client group in initClient is reported and moves the client to memory, as for a failed open.
- The memory fallback after a failed open is shared by name, like .memory (fallbackStoreProvider, MemStore).
- Drop the two SweepStorageTests for active clients, fixed on another branch.

Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859
Co-authored-by: tmm <tmm@tmm.dev>
macOS rejects DispatchSemaphore.wait() in an async context.

Amp-Thread-ID: https://ampcode.com/threads/T-c513a037-a257-45e0-b9a9-15c15edfe859
Co-authored-by: tmm <tmm@tmm.dev>
@tmm
tmm merged commit 48ca692 into main Oct 22, 2026
9 checks passed
@tmm
tmm deleted the swift-client-fixes branch October 22, 2026 03:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants