Volga
Home
Agent Skill
API Docs
GitHub
  • English
  • Русский
Home
Agent Skill
API Docs
GitHub
  • English
  • Русский
  • Home
  • Getting Started

    • Quick Start
    • Handlers
    • Route Parameters
    • Query Parameters
    • Route Groups
  • Requests & Responses

    • Headers
    • Handling JSON
    • Handling Form Data
    • Working with Files
    • Multipart Responses
    • Raw Request Body
    • Cookies
    • Validating Requests
  • Middleware & Infrastructure

    • Basic Middleware
    • Custom Middleware
    • Parameterized Middleware
    • Response Compression
    • Request Decompression
    • CORS (Cross-Origin Resource Sharing)
    • Static Files
    • Rate Limiting
    • Configuration Files
    • OpenAPI
  • Security & Access

    • Authentication and Authorization
    • OAuth 2.1 & OpenID Connect
    • OAuth 2.1 Client
    • Machine-to-Machine Grants
    • DPoP — Sender-Constrained Tokens
  • Reliability & Observability

    • Global Error Handling
    • Tracing & Logging
    • Request cancellation
    • Graceful Shutdown
  • Protocols & Realtime

    • HTTP Versions and Methods
    • HTTPS
    • WebSockets
    • Server-Sent Events (SSE)
  • Advanced Patterns

    • Dependency Injection
    • Custom Handling of HEAD, OPTIONS, and TRACE Methods
  • Agent Skill

Request cancellation

If a long-running task needs to be canceled upon a remote client closing the connection (e.g., closing a browser page), Volga supports tracking those scenarios by introducing a dedicated CancellationToken per HTTP request. Which is powered by Tokio's CancellationToken.

This is how it can be used:

use std::time::Duration;
use volga::{App, CancellationToken, ok};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new();

    // Example of long-running task
    app.map_get("/long-task", |cancellation_token: CancellationToken| async move {       
        // Running infinite loop until the remote client close the connection
        let mut interval = tokio::time::interval(Duration::from_millis(1000));

        while !cancellation_token.is_cancelled() {
            interval.tick().await;

            // Doing some long-running job...
        }

        ok!("done")
    });
    
    app.run().await
}

More robust version with using tokio::select!:

use std::time::Duration;
use volga::{App, CancellationToken, ok};

#[tokio::main]
async fn main() -> std::io::Result<()> {
    let mut app = App::new();

    // Example of long-running task
    app.map_get("/long-task", |cancellation_token: CancellationToken| async move {
        // Running infinite loop until the remote client close the connection
        tokio::select! {
            _ = cancellation_token.cancelled() => (),
            result = long_running_task() => ()
        }
        
        ok!("done")
    });
    
    app.run().await
}

async fn long_running_task() {
    let mut interval = tokio::time::interval(Duration::from_millis(100));
    loop {
        interval.tick().await;
        
        // Doing some long-running job...
    }
}

In the example above, when a remote client cancels the request, the cancellation_token.cancelled() will be finished first, and then tokio::select! will cancel the long_running_task().

This feature could help save a lot of computing resources, preventing long-running tasks from running for nothing, while fast, small tasks that run faster than 300 ms won't be affected.

When the Token Is Cancelled

A request's token belongs to its connection: it is cancelled when the connection fails — the client went away — and when a graceful shutdown runs out of time and closes the connection. A shutdown that has just started does not cancel it, since requests in flight are still answered; a handler that should wind down with the server takes a ShutdownHandle instead.

The handler is dropped along with its connection, so the token matters most for work that outlives the handler: a task it spawned, or a blocking body checking is_cancelled() as it goes. Cancelling the token from a handler notifies its clones and closes nothing.

Here you can find some additional information about CancellationToken.

Last Updated: 9/19/26, 6:56 AM
Prev
Tracing & Logging
Next
Graceful Shutdown