Commit eadcde4
fix(web,grpc): share one pooled Database, drop global mutexes, paginate /api/graph (#402)
The MCP HTTP/SSE transport got this right in #210/#217: Arc<Database>
(Sync, internally r2d2-pooled) + spawn_blocking, no lock. The web
dashboard and gRPC server never caught up:
- Web: Arc<Mutex<Database>> — every handler held a std::Mutex across its
full DB call inside an async handler (all dashboard requests
single-lane AND a blocked tokio worker), and main.rs opened a SECOND
Database (a second 16-conn pool) on the same file just for the web.
- gRPC: same Arc<Mutex<Database>>; with_db ran closures synchronously in
async fns — one slow query stalled a tonic runtime worker while
holding the global lock.
- GET /api/graph full-scanned entities and returned ALL nodes+edges
unpaginated: tens of MB of JSON at 100k entities, per dashboard
render, under that same global mutex.
Fixes, mirroring transport.rs exactly:
- main.rs wraps the one configured Database in Arc BEFORE the web block;
web + transport + stdio (mcp::run_server now takes Arc<Database>) all
share it. The second Database::open / second pool / second
set_encryption are gone — one process, one pool.
- web: WebState.db is Arc<Database>; every handler runs its DB work via
a blocking_db helper (spawn_blocking). No handler needed the old mutex
for atomicity: all six endpoints are read-only; list_entities' twin
list+count reads tolerate a racing write (documented inline).
- grpc: MnemeGrpcServer.db is Arc<Database>; with_db is async and runs
the closure on the blocking pool. sanitize_error (#354) now runs
inside the closure (Box<dyn Error> is not Send). Typed Status
passthrough (get_entity not_found) preserved. serve()/stub signatures
track the change.
- /api/graph: limit (default 500, clamp 1..=5000) + offset params;
deterministic newest-first ordering; response adds total_nodes /
returned_nodes / truncated / limit / offset. Dashboard graph tab shows
a truncation note; nodes/edges keys unchanged for compatibility.
Edges dangling outside the returned node set are dropped (previously
the unscoped path emitted edges to archived/deleted targets).
Tests (proven RED pre-fix where feasible):
- graph_default_is_capped_and_reports_totals: 510 seeded → pre-fix
returned 510 nodes (unbounded), now 500 + total_nodes=510 + truncated.
- graph_honors_limit_param_and_reports_totals: pre-fix ?limit=2 was
ignored (5 nodes); also proves offset pages are disjoint + covering.
- graph_under_cap_is_not_truncated: totals/flag correctness.
- db_closures_overlap_instead_of_serializing (web) and
rpc_db_closures_overlap_instead_of_serializing (grpc): two in-flight
DB closures rendezvous on a barrier INSIDE the closure — impossible
under the old serialize-on-mutex design (would deadlock; timeout
fails the test), deterministic proof of overlap.
- concurrent_requests_across_endpoints_all_succeed: full-stack burst
against one shared Database.
- web_state_is_send_sync_and_lock_free: type-level guard against
reintroducing Arc<Mutex<Database>>.
Closes #402
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>1 parent 2a559bd commit eadcde4
7 files changed
Lines changed: 547 additions & 167 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
36 | 51 | | |
37 | 52 | | |
38 | 53 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4468 | 4468 | | |
4469 | 4469 | | |
4470 | 4470 | | |
| 4471 | + | |
| 4472 | + | |
| 4473 | + | |
| 4474 | + | |
| 4475 | + | |
| 4476 | + | |
| 4477 | + | |
| 4478 | + | |
4471 | 4479 | | |
4472 | 4480 | | |
4473 | 4481 | | |
4474 | | - | |
| 4482 | + | |
| 4483 | + | |
| 4484 | + | |
4475 | 4485 | | |
4476 | | - | |
4477 | | - | |
4478 | | - | |
4479 | | - | |
4480 | | - | |
4481 | | - | |
4482 | | - | |
4483 | | - | |
4484 | | - | |
| 4486 | + | |
| 4487 | + | |
| 4488 | + | |
| 4489 | + | |
| 4490 | + | |
| 4491 | + | |
| 4492 | + | |
| 4493 | + | |
| 4494 | + | |
| 4495 | + | |
| 4496 | + | |
| 4497 | + | |
| 4498 | + | |
| 4499 | + | |
| 4500 | + | |
| 4501 | + | |
| 4502 | + | |
| 4503 | + | |
| 4504 | + | |
| 4505 | + | |
| 4506 | + | |
| 4507 | + | |
4485 | 4508 | | |
4486 | 4509 | | |
4487 | 4510 | | |
| |||
4493 | 4516 | | |
4494 | 4517 | | |
4495 | 4518 | | |
4496 | | - | |
| 4519 | + | |
4497 | 4520 | | |
4498 | 4521 | | |
4499 | | - | |
| 4522 | + | |
4500 | 4523 | | |
4501 | 4524 | | |
4502 | 4525 | | |
| |||
4520 | 4543 | | |
4521 | 4544 | | |
4522 | 4545 | | |
4523 | | - | |
4524 | | - | |
4525 | | - | |
4526 | | - | |
4527 | | - | |
4528 | | - | |
4529 | | - | |
4530 | | - | |
| 4546 | + | |
| 4547 | + | |
| 4548 | + | |
| 4549 | + | |
| 4550 | + | |
| 4551 | + | |
| 4552 | + | |
| 4553 | + | |
4531 | 4554 | | |
4532 | 4555 | | |
4533 | 4556 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
20 | 24 | | |
21 | | - | |
| 25 | + | |
22 | 26 | | |
23 | 27 | | |
24 | 28 | | |
25 | | - | |
| 29 | + | |
26 | 30 | | |
27 | 31 | | |
28 | 32 | | |
29 | 33 | | |
30 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
31 | 40 | | |
32 | 41 | | |
33 | 42 | | |
| |||
36 | 45 | | |
37 | 46 | | |
38 | 47 | | |
39 | | - | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
40 | 51 | | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
45 | 64 | | |
46 | 65 | | |
47 | 66 | | |
| |||
61 | 80 | | |
62 | 81 | | |
63 | 82 | | |
64 | | - | |
| 83 | + | |
65 | 84 | | |
66 | 85 | | |
67 | 86 | | |
| |||
100 | 119 | | |
101 | 120 | | |
102 | 121 | | |
| 122 | + | |
103 | 123 | | |
104 | 124 | | |
105 | 125 | | |
106 | 126 | | |
107 | | - | |
| 127 | + | |
108 | 128 | | |
109 | 129 | | |
110 | 130 | | |
| |||
136 | 156 | | |
137 | 157 | | |
138 | 158 | | |
| 159 | + | |
139 | 160 | | |
140 | 161 | | |
141 | 162 | | |
142 | 163 | | |
143 | | - | |
| 164 | + | |
144 | 165 | | |
145 | 166 | | |
146 | 167 | | |
147 | 168 | | |
148 | 169 | | |
| 170 | + | |
149 | 171 | | |
150 | 172 | | |
151 | 173 | | |
152 | 174 | | |
153 | | - | |
| 175 | + | |
154 | 176 | | |
155 | 177 | | |
156 | 178 | | |
| 179 | + | |
157 | 180 | | |
158 | 181 | | |
159 | 182 | | |
| |||
170 | 193 | | |
171 | 194 | | |
172 | 195 | | |
173 | | - | |
| 196 | + | |
174 | 197 | | |
175 | 198 | | |
176 | 199 | | |
| |||
186 | 209 | | |
187 | 210 | | |
188 | 211 | | |
| 212 | + | |
189 | 213 | | |
190 | 214 | | |
191 | 215 | | |
| |||
195 | 219 | | |
196 | 220 | | |
197 | 221 | | |
198 | | - | |
| 222 | + | |
199 | 223 | | |
200 | 224 | | |
201 | 225 | | |
| |||
207 | 231 | | |
208 | 232 | | |
209 | 233 | | |
| 234 | + | |
210 | 235 | | |
211 | 236 | | |
212 | 237 | | |
| |||
220 | 245 | | |
221 | 246 | | |
222 | 247 | | |
223 | | - | |
| 248 | + | |
224 | 249 | | |
225 | 250 | | |
| 251 | + | |
226 | 252 | | |
227 | 253 | | |
228 | | - | |
| 254 | + | |
229 | 255 | | |
230 | 256 | | |
231 | 257 | | |
| |||
234 | 260 | | |
235 | 261 | | |
236 | 262 | | |
| 263 | + | |
237 | 264 | | |
238 | 265 | | |
239 | 266 | | |
240 | | - | |
| 267 | + | |
241 | 268 | | |
242 | 269 | | |
243 | 270 | | |
| 271 | + | |
244 | 272 | | |
245 | 273 | | |
246 | | - | |
| 274 | + | |
247 | 275 | | |
248 | 276 | | |
249 | 277 | | |
| 278 | + | |
250 | 279 | | |
251 | 280 | | |
252 | 281 | | |
| |||
310 | 339 | | |
311 | 340 | | |
312 | 341 | | |
313 | | - | |
| 342 | + | |
314 | 343 | | |
315 | 344 | | |
316 | 345 | | |
| |||
333 | 362 | | |
334 | 363 | | |
335 | 364 | | |
336 | | - | |
| 365 | + | |
337 | 366 | | |
338 | 367 | | |
339 | 368 | | |
| |||
457 | 486 | | |
458 | 487 | | |
459 | 488 | | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
460 | 521 | | |
461 | 522 | | |
462 | 523 | | |
| |||
480 | 541 | | |
481 | 542 | | |
482 | 543 | | |
483 | | - | |
| 544 | + | |
484 | 545 | | |
485 | 546 | | |
486 | 547 | | |
487 | 548 | | |
488 | 549 | | |
| 550 | + | |
489 | 551 | | |
490 | 552 | | |
491 | | - | |
| 553 | + | |
492 | 554 | | |
493 | 555 | | |
494 | 556 | | |
| |||
505 | 567 | | |
506 | 568 | | |
507 | 569 | | |
508 | | - | |
| 570 | + | |
509 | 571 | | |
510 | 572 | | |
511 | 573 | | |
| |||
0 commit comments