This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
backendcritical PriorityID: axum-tower-cancellation-connection-draining-protocol

Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol

Enforces cooperative cancellation propagation, TaskTracker-bound asynchronous lifecycles, and deterministic connection draining in Axum 0.8 applications. Prevents dropped multiplexed HTTP/3 and HTTP/2 streams and incomplete database mutations during rolling updates.

Prohibited Anti-Pattern: Detaching unmonitored Tokio tasks and terminating runtimes abruptly without signaling GOAWAY frames or awaiting TaskTracker completion.

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol - Enforces cooperative cancellation propagation, TaskTracker-bound asynchronous lifecycles, and deterministic connection draining in Axum 0.8 applications. Prevents dropped multiplexed HTTP/3 and HTTP/2 streams and incomplete database mutations during rolling updates.
globs: src/**/*.rs
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/axum-tower-cancellation-connection-draining-protocol"
---

# Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol

> **Severity**: CRITICAL | **Category**: backend
> **Anti-Pattern Warning**: Detaching unmonitored Tokio tasks and terminating runtimes abruptly without signaling GOAWAY frames or awaiting TaskTracker completion.

## System Constraints
You are a Principal Rust Architect enforcing Axum 0.8, Tower, and Tokio cancellation safety and connection draining invariants. Every asynchronous task spawned across Tower middleware layers or request handlers MUST be bound to a supervised lifecycle via `tokio_util::task::TaskTracker` and propagate cancellations cooperatively using `tokio_util::sync::CancellationToken`. Ensure HTTP/2 and HTTP/3 multiplexed connections flush in-flight frames and send GOAWAY frames gracefully before shutting down listeners.

## Strict Guidelines
- Engineers MUST ALWAYS bind background side-effects spawned in handlers or Tower services to a shared `tokio_util::task::TaskTracker` and propagate a `CancellationToken` instead of issuing unbound `tokio::spawn` calls.
- Engineers MUST NOT drop raw futures containing open transactional state; handlers wrapping transactional writes MUST use an explicit scope guard or RAII rollback mechanism to ensure cancellation safety if dropped mid-stream.
- Code MUST configure `axum::serve(listener, app).with_graceful_shutdown(shutdown_signal)` and subsequently await `tracker.wait().await` with a deterministic drain deadline before runtime exit.
- Services handling multiplexed HTTP/2 or HTTP/3 streams MUST guarantee that in-flight response bodies and chunks are completely flushed before closing underlying transport quic or tcp connections.
- Components NEVER terminate the process directly on `SIGTERM` or `SIGINT`; signals MUST trip a root `CancellationToken` to trigger cooperative tree unwind.

## Bad vs Good Implementations
### Graceful Connection Draining and Cooperative Cancellation with Axum 0.8 and TaskTracker

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Using unbound `tokio::spawn` inside request handlers detaches execution from the Tower lifecycle. When a SIGTERM arrives or the connection aborts, the server process exits immediately without draining, corrupting distributed state and cutting off in-flight HTTP streams without proper GOAWAY frames.
```rust
use axum::{routing::post, Router};
use tokio::net::TcpListener;

async fn handler() -> &'static str {
    // ANTI-PATTERN: Detached naked spawn escapes server shutdown supervision;
    // if the client disconnects or SIGTERM arrives, this task leaks or is dropped non-deterministically.
    tokio::spawn(async {
        save_to_database().await;
    });
    "Accepted"
}

async fn save_to_database() {}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/job", post(handler));
    let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
    // ANTI-PATTERN: No graceful drain; incoming multiplexed requests and inflight tasks are instantly terminated.
    axum::serve(listener, app).await.unwrap();
}
```

#### Production Standard (Correct)
> **Standard**: Adheres to the cancellation protocol: background side-effects are captured by `TaskTracker` and governed by a child `CancellationToken`. `axum::serve` drains connections natively, stopping new requests and sending HTTP/2 & HTTP/3 GOAWAY frames, while `tracker.wait()` guarantees that active operations flush before the process exits.
```rust
use axum::{extract::State, routing::post, Router};
use std::{sync::Arc, time::Duration};
use tokio::net::TcpListener;
use tokio_util::sync::CancellationToken;
use tokio_util::task::TaskTracker;

#[derive(Clone)]
struct AppState {
    tracker: TaskTracker,
    token: CancellationToken,
}

async fn handler(State(state): State<Arc<AppState>>) -> &'static str {
    let token = state.token.child_token();
    // INVARIANT: Bound to TaskTracker and cooperative CancellationToken
    state.tracker.spawn(async move {
        tokio::select! {
            _ = token.cancelled() => {
                // Cooperative rollback or cleanup
            }
            _ = save_to_database() => {}
        }
    });
    "Accepted"
}

async fn save_to_database() {}

async fn shutdown_signal(token: CancellationToken) {
    tokio::signal::ctrl_c().await.expect("Failed to install CTRL+C handler");
    token.cancel();
}

#[tokio::main]
async fn main() {
    let tracker = TaskTracker::new();
    let token = CancellationToken::new();
    let state = Arc::new(AppState { tracker: tracker.clone(), token: token.clone() });
    
    let app = Router::new().route("/job", post(handler)).with_state(state);
    let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();

    let shutdown_token = token.clone();
    axum::serve(listener, app)
        .with_graceful_shutdown(shutdown_signal(shutdown_token))
        .await
        .expect("Server error");

    // Invariant: Close the tracker and wait for all in-flight tasks within a bound
    tracker.close();
    tokio::select! {
        _ = tracker.wait() => {}
        _ = tokio::time::sleep(Duration::from_secs(10)) => {
            eprintln!("Drain timeout exceeded: forcing runtime termination");
        }
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol

Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol defines an industrial-grade behavioral standard for backend engineering. Enforces cooperative cancellation propagation, TaskTracker-bound asynchronous lifecycles, and deterministic connection draining in Axum 0.8 applications. Prevents dropped multiplexed HTTP/3 and HTTP/2 streams and incomplete database mutations during rolling updates. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Detaching unmonitored Tokio tasks and terminating runtimes abruptly without signaling GOAWAY frames or awaiting TaskTracker completion. Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftDetaching unmonitored Tokio tasks and terminating runtimes abruptly without signaling GOAWAY frames or awaiting TaskTracker completion.Critical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS bind background side-effects spawned in handlers or Tower services to a shared `tokio_util

Engineers MUST ALWAYS bind background side-effects spawned in handlers or Tower services to a shared `tokio_util::task::TaskTracker` and propagate a `CancellationToken` instead of issuing unbound `tokio::spawn` calls.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT drop raw futures containing open transactional state

Engineers MUST NOT drop raw futures containing open transactional state; handlers wrapping transactional writes MUST use an explicit scope guard or RAII rollback mechanism to ensure cancellation safety if dropped mid-stream.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Code MUST configure `axum

Code MUST configure `axum::serve(listener, app).with_graceful_shutdown(shutdown_signal)` and subsequently await `tracker.wait().await` with a deterministic drain deadline before runtime exit.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services handling multiplexed HTTP/2 or HTTP/3 streams MUST guarantee that in-flight response bodies and chunks are completely flushed before closing underlying transport quic or tcp connections.

Services handling multiplexed HTTP/2 or HTTP/3 streams MUST guarantee that in-flight response bodies and chunks are completely flushed before closing underlying transport quic or tcp connections.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER terminate the process directly on `SIGTERM` or `SIGINT`

Components NEVER terminate the process directly on `SIGTERM` or `SIGINT`; signals MUST trip a root `CancellationToken` to trigger cooperative tree unwind.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is Axum 0.8 Tower Cancellation Propagation and Connection Draining Protocol critical for AI coding assistants?

Enforces cooperative cancellation propagation, TaskTracker-bound asynchronous lifecycles, and deterministic connection draining in Axum 0.8 applications. Prevents dropped multiplexed HTTP/3 and HTTP/2 streams and incomplete database mutations during rolling updates. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Detaching unmonitored Tokio tasks and terminating runtimes abruptly without signaling GOAWAY frames or awaiting TaskTracker completion.) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

Axum