Commit 9cab261
Derive toolkit MCP executors over the daemon's open database (#1409)
The daemon's boot bundle holds the data dir's ownership lock (a BEGIN
EXCLUSIVE held open on `data.db.owner-lock`, per-connection, with
`busy_timeout = 0`) for its whole lifetime. The toolkit MCP resource built
its executor with `createExecutorHandle({ activeToolkitSlug })`, which opens
a second owned database and so deadlocks against the lock this very process
holds. Every `/mcp/toolkits/<slug>` request failed with SQLITE_BUSY,
surfaced as a 500 (-32603), while the default `/mcp` resource kept working.
`activeToolkitSlug` only varies the plugin set: it adds a tool policy
provider to the toolkits plugin, while tenant, subject, and data dir are
fixed for the process. The second open was never needed. Extract the
`makeExecutor(plugins)` seam over the bundle's already-open handle and
derive toolkit executors from it, mirroring how self-host pairs a
long-lived database with per-request plugins.
The executor is built over the inner FumaDB handle rather than the owning
`{ db, close }` wrapper, so a scoped executor's `close()` tears down its own
plugins and never the shared database.
Cover both invariants in `apps/local` unit tests, which run on every PR, and
add the toolkits scenario to the e2e job that previously ran only the stdio
one. That gap is why this shipped unnoticed.
Co-authored-by: Jack <72348727+Jack-GitHub12@users.noreply.github.com>
Co-authored-by: Rhys Sullivan <39114868+RhysSullivan@users.noreply.github.com>1 parent 0004ea3 commit 9cab261
1 file changed
Lines changed: 52 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
9 | 16 | | |
10 | 17 | | |
11 | 18 | | |
| |||
52 | 59 | | |
53 | 60 | | |
54 | 61 | | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
0 commit comments