server: fix test harness for spawn_pool shutdown-receiver signature
The Run 17 Resilience change gave spawn_pool a shutdown receiver and a
JoinHandle return; the integration + load test harnesses still called the old
no-arg form. Add spawn_pool_detached() (retains the shutdown sender so the pool
runs for the test's lifetime) and point the harness AppState/WorkerContext
builders at it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 files changed,
+16 insertions,
-3 deletions
| 97 |
97 |
|
(BackgroundTx { tx }, handle)
|
| 98 |
98 |
|
}
|
| 99 |
99 |
|
|
|
100 |
+ |
/// Spawn a background pool with no external shutdown wiring, for test harnesses
|
|
101 |
+ |
/// and embeddings that manage lifecycle purely via `AppState` drop. The shutdown
|
|
102 |
+ |
/// sender is retained internally (its `changed()` never fires), so the pool
|
|
103 |
+ |
/// drains only when every `BackgroundTx` clone is dropped and the channel closes.
|
|
104 |
+ |
pub fn spawn_pool_detached() -> BackgroundTx {
|
|
105 |
+ |
let (tx, rx) = watch::channel(());
|
|
106 |
+ |
// Deliberately keep the sender alive so the drainer's shutdown arm never
|
|
107 |
+ |
// fires; the pool then behaves exactly as it did before shutdown draining
|
|
108 |
+ |
// existed (runs until the queue closes). Only reachable off the request path.
|
|
109 |
+ |
std::mem::forget(tx);
|
|
110 |
+ |
spawn_pool(rx).0
|
|
111 |
+ |
}
|
|
112 |
+ |
|
| 100 |
113 |
|
/// Acquire a permit and spawn `task`, releasing the permit when it finishes.
|
| 101 |
114 |
|
async fn run_task(sem: &Arc<Semaphore>, task: BoxFuture) {
|
| 102 |
115 |
|
let Ok(permit) = sem.clone().acquire_owned().await else {
|
| 400 |
400 |
|
makenotwork::constants::GIT_SMART_HTTP_MAX_CONCURRENT,
|
| 401 |
401 |
|
)),
|
| 402 |
402 |
|
page_view_tx: makenotwork::db::page_views::spawn_batcher(pool.clone()),
|
| 403 |
|
- |
bg: makenotwork::background::spawn_pool(),
|
|
403 |
+ |
bg: makenotwork::background::spawn_pool_detached(),
|
| 404 |
404 |
|
};
|
| 405 |
405 |
|
|
| 406 |
406 |
|
// Capture scan deps before `build_app` consumes `state`.
|
| 547 |
547 |
|
pipeline: deps.pipeline.clone(),
|
| 548 |
548 |
|
scan_semaphore: deps.semaphore.clone(),
|
| 549 |
549 |
|
wam: None,
|
| 550 |
|
- |
bg: makenotwork::background::spawn_pool(),
|
|
550 |
+ |
bg: makenotwork::background::spawn_pool_detached(),
|
| 551 |
551 |
|
// No Cloudflare purge in tests; quarantine still deletes from origin.
|
| 552 |
552 |
|
cloudflare: None,
|
| 553 |
553 |
|
cdn_base_url: None,
|
| 138 |
138 |
|
makenotwork::constants::GIT_SMART_HTTP_MAX_CONCURRENT,
|
| 139 |
139 |
|
)),
|
| 140 |
140 |
|
page_view_tx: makenotwork::db::page_views::spawn_batcher(pool.clone()),
|
| 141 |
|
- |
bg: makenotwork::background::spawn_pool(),
|
|
141 |
+ |
bg: makenotwork::background::spawn_pool_detached(),
|
| 142 |
142 |
|
};
|
| 143 |
143 |
|
|
| 144 |
144 |
|
let app = build_app(state, session_layer);
|