#![allow(clippy::unwrap_used)]
#![allow(clippy::clone_on_ref_ptr)]
#![allow(clippy::expect_used)]
use duroxide::providers::sqlite::SqliteProvider;
use duroxide::runtime::registry::ActivityRegistry;
use duroxide::runtime::{self, LogFormat, ObservabilityConfig, RuntimeOptions};
use duroxide::{ActivityContext, Client, OrchestrationContext, OrchestrationRegistry, OrchestrationStatus};
use std::sync::Arc;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let observability = ObservabilityConfig {
log_format: LogFormat::Compact,
log_level: "info".to_string(),
service_name: "duroxide-example".to_string(),
service_version: Some("1.0.0".to_string()),
..Default::default()
};
let options = RuntimeOptions {
observability,
..Default::default()
};
let store = Arc::new(SqliteProvider::new_in_memory().await?);
let activities = ActivityRegistry::builder()
.register("Greet", |ctx: ActivityContext, name: String| async move {
ctx.trace_info("Greeting activity started");
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
ctx.trace_info("Greeting activity complete");
Ok(format!("Hello, {name}!"))
})
.register("Farewell", |ctx: ActivityContext, name: String| async move {
ctx.trace_info("Farewell activity started");
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
ctx.trace_info("Farewell activity complete");
Ok(format!("Goodbye, {name}!"))
})
.build();
let greeting_orch = |ctx: OrchestrationContext, name: String| async move {
ctx.trace_info("Starting greeting orchestration");
let greeting = ctx.schedule_activity("Greet", name.clone()).await?;
ctx.trace_info(format!("Got greeting: {greeting}"));
let farewell = ctx.schedule_activity("Farewell", name).await?;
ctx.trace_info("Orchestration completing");
Ok::<_, String>(format!("{greeting} | {farewell}"))
};
let orchestrations = OrchestrationRegistry::builder()
.register("GreetingWorkflow", greeting_orch)
.build();
let rt = runtime::Runtime::start_with_options(store.clone(), activities, orchestrations, options).await;
println!("Runtime started with observability enabled");
println!("Watch the logs below with structured context fields:\n");
let client = Client::new(store);
client
.start_orchestration("greeting-1", "GreetingWorkflow", "World")
.await?;
match client
.wait_for_orchestration("greeting-1", std::time::Duration::from_secs(5))
.await
{
Ok(OrchestrationStatus::Completed { output, .. }) => {
println!("\n✅ Orchestration completed successfully!");
println!("Output: {output}");
}
Ok(OrchestrationStatus::Failed { details, .. }) => {
println!("\n❌ Orchestration failed: {}", details.display_message());
}
Ok(_) => {
println!("\n⏳ Orchestration still running");
}
Err(e) => {
println!("\n⚠️ Wait error: {e:?}");
}
}
rt.shutdown(None).await;
println!("\nRuntime shut down");
Ok(())
}