Skip to main content

Crate tower_bulkhead

Crate tower_bulkhead 

Source
Expand description

Bulkhead pattern for Tower services.

The bulkhead pattern isolates resources to prevent cascading failures. This implementation uses semaphore-based concurrency limiting to control the maximum number of concurrent calls to a service.

§Basic Example

use tower::ServiceBuilder;
use tower_bulkhead::BulkheadConfig;
use std::time::Duration;

// Create a bulkhead that allows max 10 concurrent calls
let layer = BulkheadConfig::builder()
    .max_concurrent_calls(10)
    .name("my-bulkhead")
    .build();

let service = ServiceBuilder::new()
    .layer(layer)
    .service_fn(|req: String| async move {
        // Your service logic here
        Ok::<_, ()>(req)
    });

§Example with Timeout

Configure a maximum wait duration for requests when the bulkhead is at capacity:

use tower::ServiceBuilder;
use tower_bulkhead::{BulkheadConfig, BulkheadError};
use std::time::Duration;

let layer = BulkheadConfig::builder()
    .max_concurrent_calls(5)
    .max_wait_duration(Some(Duration::from_secs(2)))
    .name("timeout-bulkhead")
    .build();

let service = ServiceBuilder::new()
    .layer(layer)
    .service_fn(|req: String| async move {
        Ok::<_, ()>(req)
    });

// Requests will timeout if they wait more than 2 seconds
// for bulkhead capacity

§Example with Event Listeners

Monitor bulkhead behavior using event listeners:

use tower::ServiceBuilder;
use tower_bulkhead::BulkheadConfig;
use std::time::Duration;

let layer = BulkheadConfig::builder()
    .max_concurrent_calls(10)
    .name("monitored-bulkhead")
    .on_call_permitted(|concurrent| {
        println!("Call permitted ({} concurrent)", concurrent);
    })
    .on_call_rejected(|max| {
        println!("Call rejected (max {} concurrent)", max);
    })
    .on_call_finished(|duration| {
        println!("Call finished in {:?}", duration);
    })
    .build();

let service = ServiceBuilder::new()
    .layer(layer)
    .service_fn(|req: String| async move {
        Ok::<_, ()>(req)
    });

§Error Handling

The bulkhead passes through the inner service’s errors directly. Use event listeners to track bulkhead rejections:

use tower_bulkhead::BulkheadConfig;
use tower::ServiceBuilder;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;

let rejections = Arc::new(AtomicUsize::new(0));
let r = rejections.clone();

let layer = BulkheadConfig::builder()
    .max_concurrent_calls(5)
    .on_call_rejected(move |_| {
        r.fetch_add(1, Ordering::SeqCst);
    })
    .build();

let service = ServiceBuilder::new()
    .layer(layer)
    .service_fn(|req: String| async move {
        Ok::<_, ()>(req)
    });

// Check rejections counter to monitor bulkhead behavior
println!("Rejections: {}", rejections.load(Ordering::SeqCst));

Re-exports§

pub use config::BulkheadConfig;
pub use config::BulkheadConfigBuilder;
pub use error::BulkheadError;
pub use error::Result;
pub use events::BulkheadEvent;
pub use layer::BulkheadLayer;
pub use service::Bulkhead;

Modules§

config
Configuration for the bulkhead pattern.
error
Error types for bulkhead pattern.
events
Event types for bulkhead pattern.
layer
Tower layer implementation for bulkhead.
service
Bulkhead service implementation.