Workflow status is tracked in GitHub: https://github.com/emulebb/emulebb-rust/issues/154. This local document is retained as the durable engineering spec and evidence record.
RUST-BUG-132 - Own daemon background tasks through graceful shutdown¶
Summary¶
Give every daemon background task explicit runtime ownership, cancellation, and bounded joining so graceful shutdown cannot race detached work that still mutates state, accesses persistence, or reinstalls services.
Current State¶
crates/emulebb-daemon/src/lib.rs starts catalog, delivery, VPN, disk, resume,
auto-connect, and diagnostics loops with detached tokio::spawn handles.
Graceful teardown begins core shutdown and stops selected services but does not
own or join those loops. The initial shared-directory monitor startup can finish
after teardown has stopped the monitor and install a new monitor while shutdown
is already in progress.
Why This Matters¶
Detached process-lifetime tasks make shutdown timing nondeterministic and can touch network or database state after finalization has begun. This is especially risky during profile restart, package smoke, and failure recovery, even when an ordinary fast shutdown appears to pass.
Representative Sites¶
crates/emulebb-daemon/src/lib.rstask spawning andgraceful_teardown.crates/emulebb-core/src/shared_dir_monitor.rsstart_shared_directory_monitorand monitor installation.- Long-running delivery, connectivity, disk, diagnostics, and resume loops.
Intended Shape¶
- Introduce one daemon task supervisor using a cancellation token and a
TaskTracker,JoinSet, or equivalent structured-concurrency owner. - Pass child cancellation explicitly to every long-running loop and startup task; do not rely only on a global flag checked at arbitrary intervals.
- Shutdown in phases: stop accepting new work, cancel producers, join tasks with bounded deadlines, then finalize network and durable state.
- Treat timeout or task panic as a surfaced shutdown failure with diagnostics, not as permission to silently abandon stateful work.
Scope Constraints¶
- Preserve stock eMule disconnect and publication semantics.
- Do not block forever on a task that ignores cancellation; joins need explicit deadlines and task names in diagnostics.
- A monitor or network runtime must not be installed after its parent runtime has entered shutdown.
- Avoid a second parallel shutdown mechanism inside core; daemon ownership and core shutdown phases must compose.
Acceptance Criteria¶
- [ ] Every daemon-spawned background task is registered with one lifecycle owner and observes explicit cancellation.
- [ ] Graceful teardown joins all registered tasks before final network and persistence resources are released.
- [ ] Shared-directory monitor startup cannot install or replace a monitor after shutdown begins.
- [ ] Task panic and join timeout identify the task and make shutdown failure observable.
- [ ] Repeated startup/shutdown and profile restart leave no orphan tasks, listeners, monitor handles, or post-shutdown database writes.
Validation¶
- Deterministic paused-time lifecycle tests for cancellation ordering.
- Delayed monitor-start regression that begins shutdown before installation.
- Task panic and timeout tests with named diagnostics.
- Existing package lifecycle smoke on every supported operating system.