Graceful Shutdown

1. Welcome and Icebreaker:

Have you ever had to restart a server in production? What happened to users’ requests?

2. Outline the Session:

Agenda:

  1. Concept Explanation: What is graceful shutdown and why is it important?
  2. Live Coding: Implement graceful shutdown in an Axum server.
  3. Tasks: Practice by simulating shutdown scenarios.

Learning Outcomes:

  • Understand the importance of graceful shutdown.
  • Implement graceful shutdown using tokio::signal in Axum.

Expectations: Try simulating a shutdown and observe how requests are handled!

3. Concept Explanation:

Graceful shutdown allows your server to finish processing in-flight requests before exiting, preventing data loss or client errors. In Axum, you can use tokio::signal to listen for termination signals (like Ctrl+C) and trigger a clean shutdown.

4. Live Coding Demonstration:

use axum::{Router, routing::get};
use tokio::signal;

async fn hello() -> &'static str {
    "Hello, Axum!"
}

#[tokio::main]
async fn main() {
    let app = Router::new().route("/", get(hello));
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await.unwrap();
    axum::serve(listener, app)
        .with_graceful_shutdown(shutdown_signal())
        .await
        .unwrap();
}

async fn shutdown_signal() {
    signal::ctrl_c().await.expect("failed to install Ctrl+C handler");
    println!("Shutting down gracefully...");
}

Best Practices:

  • Always implement graceful shutdown for production servers.
  • Log shutdown events for observability.

Common Pitfalls:

  • Not waiting for in-flight requests to finish.
  • Ignoring errors from the shutdown signal handler.

5. Tasks

  • Add a shutdown message to your logs.
  • Simulate a long-running request and observe shutdown behavior.
  • Try handling other signals (e.g., SIGTERM) for shutdown.