OXYGENHUB

Wait up to 30 seconds for SQLite's write lock eae4a97475f1

Runner log appends and claims failed with "database is locked" after the
5-second busy timeout while a release build saturated Earth's disk. Most
writers are background clients, so waiting longer beats failing
(oxygenflow#8 makes the runner retry as well).
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-09-29 00:06 UTC
Signature
✔ signed by Andy McCall
Hash
eae4a97475f1910d5322b73c99add617aac4c0e4f585758786472c90882d3baa
Depends on
d23464c0ac60
Depended on by
3b1bc27fe805 745d225de344
In bookmarks
api-unknown-fields cancel-landed-runs clear-waiting close-proposal-140 diffusion-pin-bookmark draft-ready image-check job-waits main oh-comment-body-file proposal-list-fast run-one-job wiki-says-so
In tags
v0.1.0 v0.2.0 v0.3.0 v0.3.1 v0.4.0 v0.4.1 v0.4.2 v0.5.0 v0.5.1 v0.5.2 v0.6.0 v0.6.1 v0.7.0 v0.8.0 v0.9.0 v0.9.1 v0.9.11 v0.9.15 v0.9.16 v0.9.19 v0.9.2 v0.9.20 v0.9.21 v0.9.22 v0.9.23 v0.9.24 v0.9.3 v0.9.4 v0.9.5 v0.9.6 v0.9.7 v0.9.8 v0.9.9
Edits
3 atoms, 0 tree operations, 1 file

Browse the tree at this change

modified crates/hub/src/db/mod.rs +7 −1
…
9 unchanged lines
10 10
pub type Pool = SqlitePool;
11 11
12 12
/// Open (creating if needed) and migrate the database at `path`.
13 +
/// How long a statement waits for SQLite's write lock. Most writers are
14 +
/// background clients (runners appending logs, webhook deliveries), and a
15 +
/// commit can stall for seconds while a build saturates the host's disk, so
16 +
/// waiting beats failing.
17 +
const BUSY_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(30);
18 +
13 19
pub async fn open(path: &Path) -> anyhow::Result<Pool> {
14 20
    let options = SqliteConnectOptions::new()
15 21
        .filename(path)
…
1 unchanged lines
17 23
        .journal_mode(SqliteJournalMode::Wal)
18 24
        .synchronous(SqliteSynchronous::Normal)
19 25
        .foreign_keys(true)
20 -
        .busy_timeout(std::time::Duration::from_secs(5));
26 +
        .busy_timeout(BUSY_TIMEOUT);
21 27
    let pool = SqlitePoolOptions::new().max_connections(8).connect_with(options).await?;
22 28
    sqlx::migrate!("./migrations").run(&pool).await?;
23 29
    Ok(pool)
…
6 unchanged lines