Skip to content

fix: drain accepted request work before service shutdown - #1417

Open
pjb157 wants to merge 1 commit into
mainfrom
peter/graceful-http-drain
Open

fix: drain accepted request work before service shutdown#1417
pjb157 wants to merge 1 commit into
mainfrom
peter/graceful-http-drain

Conversation

@pjb157

@pjb157 pjb157 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • keep analytics and response writers alive until Axum finishes in-flight requests
  • track and join work accepted by background=true requests before persistence shutdown
  • flush Outlet request/response capture and handler queues before cancelling writers
  • pin the reviewed Outlet lifecycle commits without using workspace patches

Incident mechanism

On SIGTERM, the control layer cancelled shared background services before accepted request and post-response persistence work had completed. That closed analytics/response-writer channels while requests were still draining, producing the observed channel closed failures.

Dependencies

Merge in order:

  1. feat: add graceful request logger drain outlet#99
  2. chore: use outlet graceful drain support outlet-postgres#83
  3. this PR

The git revisions make this branch reproducible before crate releases; they can be replaced with released versions in normal dependency maintenance.

Verification

  • CARGO_PROFILE_DEV_DEBUG=0 CARGO_INCREMENTAL=0 just lint rust
  • DATABASE_URL=postgresql://localhost/dwctl_graceful_drain_20260731 RUST_TEST_THREADS=4 CARGO_PROFILE_TEST_DEBUG=0 CARGO_INCREMENTAL=0 just test rust
    • dwctl: 1917 passed, 2 ignored
    • all workspace unit, integration, and doc tests passed
  • targeted graceful shutdown ordering test passed
  • full Outlet and outlet-postgres test/lint suites passed in their prerequisite PRs

Copilot AI review requested due to automatic review settings July 31, 2026 19:45
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploying control-layer with  Cloudflare Pages  Cloudflare Pages

Latest commit: eed501b
Status: ✅  Deploy successful!
Preview URL: https://530b0a9f.control-layer.pages.dev
Branch Preview URL: https://peter-graceful-http-drain.control-layer.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes graceful shutdown ordering so persistence-related background services (analytics, response writers, Outlet handlers) remain available while Axum drains in-flight requests, and it ensures background=true “accepted” work is joined before persistence shuts down. It also pins outlet / outlet-postgres to specific git revisions to pick up the lifecycle/shutdown behavior needed for the fix.

Changes:

  • Introduce an Outlet shutdown handle and a cancel_after_drain helper to flush/join accepted work and then cancel background services only after HTTP draining completes.
  • Track detached “accepted” work via a tokio_util::task::TaskTracker, and route background=true tasks through that tracker.
  • Pin outlet / outlet-postgres dependencies to specific git revs and update the workspace lockfile accordingly.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
dwctl/src/lib.rs Refactors router construction to return an optional Outlet shutdown handle; adds accepted-task tracking and enforces post-drain shutdown ordering.
dwctl/src/inference/middleware.rs Routes detached background request work through a shared TaskTracker so it can be drained on shutdown.
dwctl/Cargo.toml Enables tokio-util runtime feature and pins outlet / outlet-postgres to git revisions.
Cargo.lock Records the git-sourced outlet / outlet-postgres dependencies (and transitive updates) for reproducible builds.

Comment thread dwctl/src/lib.rs Outdated
Comment on lines +3458 to +3462
result = cancel_after_drain(
axum::serve(listener, service.into_make_service()).with_graceful_shutdown(shutdown),
accepted_tasks,
outlet_shutdown,
shutdown_token,
Comment thread dwctl/src/lib.rs Outdated
Comment on lines +3530 to +3534
if let Some(outlet_shutdown) = outlet_shutdown
&& let Err(error) = outlet_shutdown.shutdown().await
{
tracing::error!(%error, "Outlet request logger worker panicked during shutdown");
}
Comment thread dwctl/Cargo.toml
Comment on lines +92 to +93
outlet = { git = "https://github.com/doublewordai/outlet", rev = "6206a0bedc0c9a5d1ad77b837ec334642d06eea8" }
outlet-postgres = { git = "https://github.com/doublewordai/outlet-postgres", rev = "e7c8d8ee7c633183eb52ea533ef0bbdb19120a59" }
@pjb157
pjb157 force-pushed the peter/graceful-http-drain branch 3 times, most recently from bb15a6b to e0c8b5f Compare July 31, 2026 20:10
@pjb157
pjb157 force-pushed the peter/graceful-http-drain branch from e0c8b5f to eed501b Compare July 31, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants