Skip to content
This repository was archived by the owner on Sep 12, 2018. It is now read-only.

Thoughts: modeling db conn in Rust

Richard Newman edited this page Jan 9, 2017 · 1 revision

A store consists conceptually of an on-disk database (SQLite), and a collection of in-memory metadata derived from the database. This metadata includes the symbolic and numeric schema, mappings from idents to entids and back again, a table of part numbers, a current transaction counter, and more: e.g., we will likely add a last-schema-change-tx-id to invalidate schema-dependent pre-work.

Writes are (at least conceptually) executed sequentially, and are queued for convenience.

Writes that change the schema/metadata are uncommon.

Reads can occur in parallel.

Reads and writes involve some interpretation — e.g., mapping idents to entids according to the schema — and that interpretation necessarily must seem to occur against the schema at the moment of their execution.

Reads and writes are isolated. That implies that the results of a read (which are themselves interpreted according to metadata) are interpreted against the database upon which the read ran, regardless of a simultaneous write that might have separately changed the schema.

So:

  • A conn maintains a reference to the current DB and the writer. The writer must be able to replace the current DB with a new DB. Multiple threads and readers can maintain read-only references to an individual DB in order to interpret query results or consistently make API calls.
  • A query requires only a SQLite connection and a read-only reference to a DB. The DB’s schema is used to interpret queries and results.
  • Reads use a (perhaps read-only) SQLite connection, likely drawn from a pool or reserved for private use.
  • A write requires the writer SQLite connection and a DB (used to interpret the next write), optionally returning a new derived DB.
  • Writes are queued. A single writer owns a SQLite connection, and is associated with a thread.
  • The initial DB is built by issuing database reads (fetching parts, idents, schema) within a transaction.
  • => DB instances can be immutable. They’re shared across threads, with varying lifetimes, and so must be Arc, but they’re never modified.
  • => A conn is effectively a thread with which one communicates by message passing.
  • => A conn’s current-db can be read from multiple threads — to get an immutable DB ref that we can use for querying — and written by one, the writer. That implies a RwLock. Only the writer will ever take the write lock.
  • => In order to avoid cycles, the writer loop itself can’t hold a reference to the conn!

Clone this wiki locally