Volga
Home
API Docs
GitHub
  • English
  • Русский
Home
API Docs
GitHub
  • English
  • Русский
  • Home
  • Basics

    • Quick Start
    • Route Parameters
    • Query Parameters
    • Route Groups
    • Headers
  • Data Formats

    • Handling JSON
    • Handling Form Data
    • Working with Files
    • Server-Sent Events (SSE)
  • Protocols

    • HTTP/1 and HTTP/2
    • HTTPS
    • WebSockets & WebTransport
  • Advanced

    • Custom Middleware
    • Response Compression
    • Request Decompression
    • Global Error Handling
    • Dependency Injection
    • Tracing & Logging
    • Static Files
    • CORS (Cross-Origin Resource Sharing)
    • Cookies
    • Request cancellation
    • Custom Handling of HEAD, OPTIONS, and TRACE Methods

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.

Here you can find some additional information about CancellationToken.

Last Updated:
Prev
Cookies
Next
Custom Handling of HEAD, OPTIONS, and TRACE Methods