You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix a panic on `/new` caused by SQLite lock contention when `ForgeRepo` created a second connection pool pointing at the same `.forge.db` file while the previous pool was still alive.
3
+
4
+
## Context
5
+
Every time a user ran `/new`, `ForgeRepo::new` created a brand-new `DatabasePool` via `DatabasePool::try_from(...).unwrap()`. The old pool — still held alive by `tokio::spawn`'d hydration tasks — would hold open connections to the same SQLite file. r2d2's pool builder validates connections at construction time with a 5-second timeout; after 5 retries the error bubbled back to the `.unwrap()`, crashing the process with:
6
+
7
+
```
8
+
ERROR: called `Result::unwrap()` on an `Err` value: Failed to create connection pool: timed out waiting for connection
9
+
```
10
+
11
+
## Changes
12
+
-**`forge_repo`**: `ForgeRepo::new` now accepts an `Arc<DatabasePool>` instead of constructing its own. The `DatabasePool` and `PoolConfig` types are re-exported from the crate root so callers don't need to reach into internal modules.
13
+
-**`forge_api`**: `ForgeAPI::init` creates the pool once and passes it to `ForgeRepo::new`. The return type changes from `Self` to `Result<Self>` so a pool failure produces a clean error message instead of a panic.
14
+
-**`forge_main`**: `UI`'s factory closure type changes from `Fn(ForgeConfig) -> A` to `Fn(ForgeConfig) -> Result<A>` to accommodate the fallible `ForgeAPI::init`. `on_new` propagates the error via `?` instead of unwrapping.
15
+
16
+
### Key Implementation Details
17
+
The pool is now created once per `forge` process — inside `ForgeAPI::init` using `ConfigReader::base_path().join(".forge.db")`, which is the canonical path already used by `Environment::database_path()`. On each `/new`, a new `ForgeRepo` is built pointing at the same `Arc<DatabasePool>`, so the underlying SQLite file is only ever opened once and there is no contention window.
0 commit comments