TestConcurrentWritesAllSucceed (internal/database/concurrent_writes_internal_test.go), the test that #198 added, fails on next (15d9543) when the host is busy. In script/cibuild the first test run passed; the second, built at the same time as the lint phase, failed in the case db_url without parameters:
writer 2: counting a cache hit: database is locked (5) (SQLITE_BUSY)
hit_count = 66 and 66 source_content rows, want 80 of each
So next is not reliably green. The test shows a real defect, not a flaky test. pixa adds busy_timeout(5000) to db_url, but a write that keeps losing the race to the other connections can still wait longer than 5 seconds, and its write is lost. A busy server under disk load loses writes the same way.
Definition of done
Concurrent writes from separate goroutines never fail with database is locked, with or without parameters in db_url, also when the host is under load.
The fix is in the code, not the test: TestConcurrentWritesAllSucceed keeps its writers, requests and assertions.
Recommended fix: limit the *sql.DB to one open connection (SetMaxOpenConns(1)), so that pixa's own writes queue in Go instead of competing for SQLite's lock. Before relying on it, check every place that keeps rows, a statement or a transaction open while it runs another query on the same *sql.DB. With one connection, that would wait forever. Any such place is fixed in the same change, and a test covers it if one does not already. If that turns out not to work, say why on the PR and take the next simplest fix that meets the first point.
README.md / configs/config.example.yml change only where they describe how pixa uses the database, if they do.
script/cibuild passes, including its second test run made while the lint phase builds.
Model: opus-5-5
`TestConcurrentWritesAllSucceed` (`internal/database/concurrent_writes_internal_test.go`), the test that https://git.eeqj.de/sneak/pixa/issues/198 added, fails on `next` (`15d9543`) when the host is busy. In `script/cibuild` the first test run passed; the second, built at the same time as the lint phase, failed in the case `db_url without parameters`:
```
writer 2: counting a cache hit: database is locked (5) (SQLITE_BUSY)
hit_count = 66 and 66 source_content rows, want 80 of each
```
So `next` is not reliably green. The test shows a real defect, not a flaky test. pixa adds `busy_timeout(5000)` to `db_url`, but a write that keeps losing the race to the other connections can still wait longer than 5 seconds, and its write is lost. A busy server under disk load loses writes the same way.
## Definition of done
- Concurrent writes from separate goroutines never fail with `database is locked`, with or without parameters in `db_url`, also when the host is under load.
- The fix is in the code, not the test: `TestConcurrentWritesAllSucceed` keeps its writers, requests and assertions.
- Recommended fix: limit the `*sql.DB` to one open connection (`SetMaxOpenConns(1)`), so that pixa's own writes queue in Go instead of competing for SQLite's lock. Before relying on it, check every place that keeps rows, a statement or a transaction open while it runs another query on the same `*sql.DB`. With one connection, that would wait forever. Any such place is fixed in the same change, and a test covers it if one does not already. If that turns out not to work, say why on the PR and take the next simplest fix that meets the first point.
- `README.md` / `configs/config.example.yml` change only where they describe how pixa uses the database, if they do.
- `script/cibuild` passes, including its second test run made while the lint phase builds.
Model: opus-5-5
clawbot
self-assigned this 2026-10-08 02:24:23 +02:00
#225 takes the recommended fix: the database now has one open connection, so pixa's own writes wait their turn instead of racing for SQLite's lock. No code in internal/database or internal/imgcache keeps rows or a transaction open while it runs another query, so nothing needed changing for that. The other test that failed on the same busy host is #224.
Model: opus-5-5
https://git.eeqj.de/sneak/pixa/pulls/225 takes the recommended fix: the database now has one open connection, so pixa's own writes wait their turn instead of racing for SQLite's lock. No code in `internal/database` or `internal/imgcache` keeps rows or a transaction open while it runs another query, so nothing needed changing for that. The other test that failed on the same busy host is https://git.eeqj.de/sneak/pixa/issues/224.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
TestConcurrentWritesAllSucceed(internal/database/concurrent_writes_internal_test.go), the test that #198 added, fails onnext(15d9543) when the host is busy. Inscript/cibuildthe first test run passed; the second, built at the same time as the lint phase, failed in the casedb_url without parameters:So
nextis not reliably green. The test shows a real defect, not a flaky test. pixa addsbusy_timeout(5000)todb_url, but a write that keeps losing the race to the other connections can still wait longer than 5 seconds, and its write is lost. A busy server under disk load loses writes the same way.Definition of done
database is locked, with or without parameters indb_url, also when the host is under load.TestConcurrentWritesAllSucceedkeeps its writers, requests and assertions.*sql.DBto one open connection (SetMaxOpenConns(1)), so that pixa's own writes queue in Go instead of competing for SQLite's lock. Before relying on it, check every place that keeps rows, a statement or a transaction open while it runs another query on the same*sql.DB. With one connection, that would wait forever. Any such place is fixed in the same change, and a test covers it if one does not already. If that turns out not to work, say why on the PR and take the next simplest fix that meets the first point.README.md/configs/config.example.ymlchange only where they describe how pixa uses the database, if they do.script/cibuildpasses, including its second test run made while the lint phase builds.Model: opus-5-5
#225 takes the recommended fix: the database now has one open connection, so pixa's own writes wait their turn instead of racing for SQLite's lock. No code in
internal/databaseorinternal/imgcachekeeps rows or a transaction open while it runs another query, so nothing needed changing for that. The other test that failed on the same busy host is #224.Model: opus-5-5