Skip to main content

all_settled

Macro all_settled 

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

Waits for all futures to settle, returning all outcomes.

This macro boxes each future to enable combining heterogeneous future types, then delegates to ctx.all_settled(). Unlike all!, this macro does not short-circuit on failure - it waits for all futures to complete and returns a BatchResult containing all outcomes.

§Arguments

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

§Returns

  • Ok(BatchResult<T>) - Contains outcomes for all futures (never fails)

The BatchResult provides methods to:

  • successes() / succeeded() - Get successful results
  • failures() / failed() - Get failed results
  • success_count() / failure_count() - Count outcomes
  • all_succeeded() / has_failures() - Check overall status
  • get_results() - Get all successful results or error if any failed

§Examples

§Collecting All Outcomes

use durable_execution_sdk::all_settled;

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

let batch = all_settled!(ctx,
    async move { ctx1.step(|_| Ok(1), None).await },
    async move { ctx2.step(|_| Err::<i32, _>("failed".into()), None).await },
    async move { ctx3.step(|_| Ok(3), None).await },
).await?;

println!("Total: {}", batch.items.len());        // 3
println!("Succeeded: {}", batch.success_count()); // 2
println!("Failed: {}", batch.failure_count());    // 1

§Processing Successes and Failures Separately

use durable_execution_sdk::all_settled;

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

let batch = all_settled!(ctx,
    async move { ctx1.step(|_| process_item_a(), None).await },
    async move { ctx2.step(|_| process_item_b(), None).await },
    async move { ctx3.step(|_| process_item_c(), None).await },
).await?;

// Process successful results
for item in batch.succeeded() {
    if let Some(result) = item.get_result() {
        println!("Success: {:?}", result);
    }
}

// Log failures for retry or investigation
for item in batch.failed() {
    if let Some(error) = item.get_error() {
        eprintln!("Failed at index {}: {:?}", item.index, error);
    }
}

§Partial Success Handling

use durable_execution_sdk::all_settled;

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

let batch = all_settled!(ctx,
    async move { ctx1.step(|_| send_notification_email(), None).await },
    async move { ctx2.step(|_| send_notification_sms(), None).await },
    async move { ctx3.step(|_| send_notification_push(), None).await },
).await?;

if batch.all_succeeded() {
    println!("All notifications sent!");
} else {
    println!("Sent {} of {} notifications",
        batch.success_count(),
        batch.items.len()
    );
}

§Order Preservation

Results are returned in the same order as input futures:

use durable_execution_sdk::all_settled;

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

let batch = all_settled!(ctx,
    async move { ctx1.step(|_| Ok("first"), None).await },
    async move { ctx2.step(|_| Ok("second"), None).await },
    async move { ctx3.step(|_| Ok("third"), None).await },
).await?;

assert_eq!(batch.items[0].index, 0);
assert_eq!(batch.items[1].index, 1);
assert_eq!(batch.items[2].index, 2);

§When to Use

Use all_settled! when you need to:

  • Collect all outcomes regardless of individual success/failure
  • Implement partial success handling
  • Gather errors for logging or retry logic
  • Process results even when some operations fail

§See Also

  • all! - Fail fast on first error
  • any! - Return first success
  • race! - Return first to settle