0 Thoughts: modeling db conn in Rust
Richard Newman edited this page 2017-01-09 11:32:29 -08:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 DBs 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. Theyre shared across threads, with varying lifetimes, and so must be Arc, but theyre never modified.
  • => A conn is effectively a thread with which one communicates by message passing.
  • => A conns 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 cant hold a reference to the conn!