Skip to content

fix(openontology): migrate in one transaction, and stop timing out on slow disks - #124

Merged
ralyodio merged 1 commit into
masterfrom
fix/flaky-libsql-timeout
Aug 3, 2026
Merged

fix(openontology): migrate in one transaction, and stop timing out on slow disks#124
ralyodio merged 1 commit into
masterfrom
fix/flaky-libsql-timeout

Conversation

@ralyodio

@ralyodio ralyodio commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Why

CI failed on #123 — a marketing-copy PR that cannot touch this package — when packages/openontology/src/libsql.test.ts"seeds a package and hydrates it back identically" hit vitest's default 5000ms timeout. Re-running the same commit passed, so it is a flake, and it will keep landing on unrelated PRs until the underlying variance is removed.

The assertions were never wrong. The suite is I/O bound and the runner was slow. Locally the whole file runs in ~250ms with the slowest case at 79ms, so CI diverged by 60×+.

What

1. Batch each migration into one write transaction. migrate() ran every DDL statement through its own client.execute(). Migration 1 is ~30 statements, so opening a store cost ~30 separate durable commits — and every test in the file opens several stores.

Measured on a local SSD, 25 fresh migrations:

before   206ms / 208ms total   → 8.2ms each
after    124ms total           → 5.0ms each

~40% off where fsync is cheap; the win grows as durability gets more expensive, which is exactly the CI case.

This also closes a real hole. The DDL and the schema_migrations bookkeeping insert were not atomic, so a crash part-way could leave the schema half-applied while the migration was recorded as complete. Now they commit together.

Safe to batch: every statement is CREATE ... IF NOT EXISTS (tables, indexes, and one fts5 virtual table). No PRAGMAs, no triggers.

2. Give the package a 30s testTimeout/hookTimeout. These suites drive a real file-backed SQLite database through @libsql/client, so wall time is set by the host filesystem rather than by our code. The 5s default is tuned for CPU-bound unit tests. A slow disk should report as slow, not as a spurious failure.

Verification

  • vitest run src in packages/openontology148 passed, five consecutive runs, no flake.
  • vitest run contract in apps/logicsrc-web71 passed, including the 25 ontology-API tests that are the only downstream consumer of createLibsqlStore.
  • tsc build clean for the package and its dependents.

Timeout #2 is the safety net; the batching in #1 is the part that actually reduces the variance.

🤖 Generated with Claude Code

… slow disks

CI failed on an unrelated PR when "seeds a package and hydrates it back
identically" passed vitest's default 5s timeout. The assertions were
fine; the suite is I/O bound and the runner was slow. Two changes.

migrate() ran every DDL statement through its own client.execute(), so
migration 1's ~30 statements each became a separate durable commit and
opening a store paid ~30 fsyncs. Batch each migration into one write
transaction instead: locally a fresh migration drops from ~8.2ms to
~5.0ms, and the gap widens as fsync gets more expensive. It also closes
a real hole -- a crash part-way could previously leave the schema
half-applied while schema_migrations recorded the migration as done,
because the statements and the bookkeeping insert were not atomic.

Then give the package a 30s testTimeout. These suites drive a real
file-backed SQLite database, so their wall time is set by the host
filesystem, not by our code. The 5s default is tuned for CPU-bound unit
tests and leaves no headroom on a contended runner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

vu1nz Security Review

0 finding(s) in PR #?

No security issues found.

@ralyodio
ralyodio marked this pull request as ready for review August 3, 2026 13:35
@ralyodio
ralyodio merged commit 806e781 into master Aug 3, 2026
5 checks passed
@ralyodio
ralyodio deleted the fix/flaky-libsql-timeout branch August 3, 2026 13:44
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.

1 participant