registry: set busy_timeout before journal_mode=WAL (#1239)
journal_mode=WAL takes a lock, and with no busy_timeout applied yet, two processes opening the registry at once (the router starting while add-instance or the tunnel gateway runs) can fail immediately with SQLITE_BUSY instead of waiting their turn. Order the pragmas so the timeout is in place before WAL. Found while porting the router for titogo, which has carried this fix since.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 file changed,
+5
−1
registry.go+5 −1
diff --git a/registry.go b/registry.go| index a19371a..d288175 100644 |
| --- a/registry.go |
| +++ b/registry.go |
| @@ -112,9 +112,13 @@ func openRegistry(path string) (*Registry, error) { |
| } |
| // One writer at a time keeps WAL happy (mirrors openDB). |
| d.SetMaxOpenConns(1) |
| + // busy_timeout FIRST: two processes open this DB concurrently (the router |
| + // starting while add-instance or the tunnel gateway runs), and |
| + // journal_mode=WAL takes a lock — with no timeout set yet the loser fails |
| + // immediately with SQLITE_BUSY instead of waiting its turn. |
| for _, p := range []string{ |
| - "PRAGMA journal_mode=WAL", |
| "PRAGMA busy_timeout=5000", |
| + "PRAGMA journal_mode=WAL", |
| "PRAGMA synchronous=NORMAL", |
| } { |
| if _, err := d.Exec(p); err != nil { |