Skip to main content

race

Macro race 

Source
macro_rules! race {
    ($ctx:expr, $($fut:expr),+ $(,)?) => { ... };
}
Expand description

Returns the result of the first future to settle (success or failure).

This macro boxes each future to enable combining heterogeneous future types, then delegates to ctx.race(). All futures run concurrently, and the macro returns as soon as any future completes, regardless of whether it succeeded or failed.

§Arguments

  • $ctx - The DurableContext instance
  • $fut - One or more future expressions (comma-separated)

§Returns

  • Ok(T) - If the first future to settle succeeded
  • Err(DurableError) - If the first future to settle failed

§Examples

§Timeout Pattern

use durable_execution_sdk::race;

let ctx1 = ctx.clone();
let ctx2 = ctx.clone();

// Race between operation and timeout
let result = race!(ctx,
    async move { ctx1.step(|_| slow_operation(), None).await },
    async move {
        ctx2.step(|_| {
            std::thread::sleep(std::time::Duration::from_secs(5));
            Err::<String, _>("timeout".into())
        }, None).await
    },
).await;

match result {
    Ok(data) => println!("Operation completed: {}", data),
    Err(e) => println!("Timed out or failed: {}", e),
}

§Competitive Operations

use durable_execution_sdk::race;

let ctx1 = ctx.clone();
let ctx2 = ctx.clone();

// Use whichever service responds first
let result = race!(ctx,
    async move { ctx1.step(|_| call_service_a(), None).await },
    async move { ctx2.step(|_| call_service_b(), None).await },
).await?;

§First Failure Wins

use durable_execution_sdk::race;

let ctx1 = ctx.clone();
let ctx2 = ctx.clone();

// If the first to settle is an error, that error is returned
let result = race!(ctx,
    async move { ctx1.step(|_| Err::<i32, _>("fast error".into()), None).await },
    async move {
        ctx2.step(|_| {
            std::thread::sleep(std::time::Duration::from_millis(100));
            Ok(42)
        }, None).await
    },
).await;

assert!(result.is_err()); // Error settled first

§When to Use

Use race! when you want the first result regardless of success or failure. This is useful for timeout patterns or when competing operations should cancel each other. Unlike any!, race! returns immediately on the first settlement, even if it’s a failure.

§See Also

  • all! - Wait for all to succeed
  • any! - Return first success (ignores failures)
  • all_settled! - Collect all outcomes