-
Notifications
You must be signed in to change notification settings - Fork 0
docs: document SqliteStore::share_for_device #510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
242e013
daaeaa1
b160802
48ad1fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -521,6 +521,32 @@ impl SharedSqlite { | |
| `read` takes a permit from a separate reader pool, sized by [`SqliteStoreConfig::read_pool_size`](/concepts/storage#memory-and-thread-tuning-sqlitestoreconfig). A burst of reads can then run alongside a pending write instead of queueing behind `run`'s write-path permits. If `read_pool_size` is `0` (the default) or the underlying connection isn't WAL, `read` falls back to queueing on the same permits as `run` — it's always safe to call. Wrapping the closure in a deferred transaction also means a `read` that issues more than one statement (e.g. resolve a chat's identity keys, then query by them) sees one consistent snapshot across all of them, rather than possibly straddling a write that commits in between. Prefer `read` over `run` for anything that only queries. [`whatsapp-rust-chat-store`](/api/chat-store)'s query paths do, and so does most of `SqliteStore`'s own `SignalStore`/`AppSyncStore`/`ProtocolStore`/`DeviceStore` surface as of [whatsapp-rust#1222](https://github.com/oxidezap/whatsapp-rust/pull/1222) — session, identity, sender-key, and pre-key lookups among them. A handful of reads are deliberately kept on `run` instead: a stale answer for these would go out on the wire, fail an operation outright, or overwrite a cache unconditionally (app-state sync key lookups, `messageSecret` reads, `get_devices`). | ||
| </Note> | ||
|
|
||
| ### Sharing the pool with sibling devices | ||
|
|
||
| ```rust | ||
| pub fn share_for_device(&self, device_id: i32) -> Self; | ||
| ``` | ||
|
|
||
| `SqliteStore::share_for_device()` returns a new `SqliteStore` for a *sibling device* in the same database file, cloning this store's pool, write-serialization semaphore, and reader pool instead of opening another connection. Every constructor builds its own r2d2 pool, so a process holding N sessions against one database file today opens N connections — and a connection costs memory before it reads a single row: a fixed ~46.9 KiB lookaside slab (`SQLITE_DEFAULT_LOOKASIDE`, not reducible via any pragma — `SQLITE_DBCONFIG_LOOKASIDE` is C-API only and unreachable through diesel) plus a page cache that grows to [`cache_size_kib`](#database-configuration). Since every query already carries a `device_id`, sibling sessions on one database only ever needed that field to differ. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Break this paragraph into shorter sentences. It combines pool construction, connection counts, lookaside configuration, page-cache behavior, and device scoping in one dense line, which violates the project's requirement to keep sentences concise and cover one idea at a time. The similarly long performance sentence below should be split as part of the same correction. AGENTS.md reference: AGENTS.md:L25-L25 Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Qualify the 46.9 KiB figure as applying to the tested bundled SQLite build. Useful? React with 👍 / 👎. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Scope the claim that N sessions open N connections to the default configuration. Useful? React with 👍 / 👎. |
||
|
|
||
| ```rust | ||
| use whatsapp_rust_sqlite_storage::SqliteStore; | ||
|
|
||
| let device_1 = SqliteStore::new_for_device("whatsapp.db", 1).await?; | ||
| // One pool, one connection, two sessions. | ||
| let device_2 = device_1.share_for_device(2); | ||
| ``` | ||
|
|
||
| The returned store owns clones of the pool handles, so it stays usable for as long as it lives — dropping the store it came from closes nothing. | ||
|
|
||
| What it does **not** do: | ||
|
|
||
| - **Create the device row.** It only stamps queries with `device_id`; the row still comes from the usual provisioning path (`create_new_device` or restore), same as a store built with `new_for_device`. | ||
| - **Isolate writes.** Siblings share the write permits set by [`SqliteStoreConfig::pool_size`](#database-configuration) — at the default of `1`, their writes serialize against each other. Measured on a burst where every sibling writes continuously, sharing costs roughly 2.5x the aggregate write throughput of a pool per session, in exchange for FIFO-fair scheduling across siblings (a private connection per session instead leaves fairness to SQLite's busy handler, which backs off randomly — about 2x the spread between the fastest and slowest session). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Correct the fairness comparison for the documented Useful? React with 👍 / 👎. |
||
| - **Split `resource_report()`.** Siblings share one pool, so every handle reports the same whole-pool estimate — when summing across a fleet of siblings, count it once per pool, not once per handle. | ||
|
|
||
| Because of the write-serialization trade, this is for **mostly-idle fleets** — sessions that are connected but not writing continuously, which is the common shape — rather than a default replacement for a store per session. See [Memory and Thread Tuning](/concepts/storage#memory-and-thread-tuning-sqlitestoreconfig) for measured numbers. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Features | ||
|
|
||
| - **Connection pooling** - Uses Diesel r2d2 with pool size of 2 | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.