Introduce Storage trait abstracting durable-runtime DB queries#101
Merged
thinkingfish merged 6 commits intomainfrom May 5, 2026
Merged
Introduce Storage trait abstracting durable-runtime DB queries#101thinkingfish merged 6 commits intomainfrom
thinkingfish merged 6 commits intomainfrom
Conversation
Move every sqlx query against the durable schema in `worker.rs`, `task.rs`, and `plugin/durable/notify.rs` behind a new `Storage` trait, with a `PgStorage` impl that holds the existing query bodies verbatim. Transaction lifecycle (`pool.begin()`, `pool.acquire()`, commit/rollback) stays at the call sites — methods take a borrowed `&mut sqlx::PgConnection`, which works for both pooled connections and transactions via sqlx's `Executor` blanket impl. This is a mechanical refactor with no functional or behavioural changes. The trait is the scaffolding for a future swappable backend (e.g. SQLite with a polling executor); for now it is `pub(crate)` and Postgres-typed. The new `.sqlx/query-*.json` files are regenerated cache entries for the queries whose surrounding code indentation changed when they moved into trait-method bodies. Their describe info is identical to the previous entries — only the literal whitespace in the SQL string differs.
Use auto-deref for &mut Transaction at four call sites in plugin/durable/notify.rs (clippy::explicit_auto_deref) and replace a match with Option::unwrap_or in worker.rs::load_leader_id (clippy::manual_unwrap_or).
* Add the missing cache entry for `SELECT state = 'suspended' as "state!"`,
used at 5 call sites in `durable-test/tests/it/{notify,dst_notify}.rs`.
Without it, those tests failed to compile under `SQLX_OFFLINE=true`.
* Delete 21 unused cache entries left over from the storage refactor.
Most were entries for the old SQL strings whose surrounding indentation
changed when the queries moved into trait-method bodies in
`crates/durable-runtime/src/storage/pg.rs`; the rest were pre-existing
orphans.
After this commit, every entry under `.sqlx/` matches a query somewhere in
the workspace and every macro-checked query has a matching entry.
Per the project's commenting policy, remove doc comments that just restate the method or type name. Keep ones that explain why behaviour exists, document constraints, or describe non-obvious return semantics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase 1 of the storage abstraction discussed in https://claude.ai/code/session_013icXPFch1CZdPwMb5Mmu1S — a mechanical move of every
sqlx::query!against the durable schema inworker.rs,task.rs, andplugin/durable/notify.rsbehind a newStoragetrait, with aPgStorageimpl holding the existing query bodies verbatim.The trait exists so a future swappable backend (e.g. SQLite with a polling executor) can be added without further restructuring. For now it is
pub(crate)and Postgres-typed.What this PR does NOT change
pool.begin(),pool.acquire(),commit/rollback). Trait methods take a borrowed&mut sqlx::PgConnection, which works for both pooled connections and transactions via sqlx'sExecutorblanket impl.enter/exitdecision logic, error handling paths, and thecommit_event_with_logCTE all behave identically.Notes for review
TaskStateenum (thedurable.task_statePostgres enum mapping) moved fromplugin/durable/notify.rsintostorage::modso both the runtime and the notify plugin share it.SharedStategains anArc<dyn Storage>field next to the existingpool: PgPool. Both reference the same pool. Phase 2 can collapse to one..sqlx/was tidied as part of this PR: 18 new entries added for queries whose surrounding indentation changed when they moved into trait-method bodies, 21 unused entries deleted (the now-orphaned old strings plus 3 pre-existing orphans), and 1 missing entry added forSELECT state = 'suspended' as "state!"used at 5 call sites indurable-test/tests/it/{notify,dst_notify}.rs— socargo build --workspace --testsis green underSQLX_OFFLINE=truefor the first time on this branch. After this PR, every.sqlx/entry maps to a query in the workspace and every macro-checked query has a matching entry.commit_event_with_logis one CTE, etc.); methods whose names already convey their behaviour are left undocumented. No comment leaks impl-specific constants.Out of scope
plugin/durable/sql/— that's a separate concern (the wasm guest's SQL dialect).EventSourcetrait already exists for that swap; this PR doesn't touch it.Conn/Txtypes,Storageowning transaction lifecycle, removingpool: PgPoolfromSharedState).Test plan
cargo check -p durable-runtime --all-targetscleancargo +nightly fmt --checkcleancargo clippy -p durable-runtime --all-targetscleancargo test -p durable-runtime --libpasses (15/15)cargo build --workspace --testssucceeds underSQLX_OFFLINE=true🤖 Generated with Claude Code