Skip to content

Commit 6b75b4e

Browse files
committed
feat(docs): update examples in observers, recovery, and saga sections to use async main function
1 parent d3502b1 commit 6b75b4e

3 files changed

Lines changed: 119 additions & 84 deletions

File tree

docs/content/observers/_index.md

Lines changed: 53 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,19 @@ impl WorkflowObserver for TaskCounter {
7777
}
7878
}
7979

80-
let counter = Arc::new(TaskCounter::default());
81-
82-
let workflow = Workflow::bare()
83-
.register(Step::Start, DoWork)
84-
.add_exit_state(Step::Done)
85-
.with_observer(counter.clone());
86-
87-
workflow.orchestrate(Step::Start).await?;
88-
assert_eq!(counter.0.load(Ordering::Relaxed), 1);
80+
#[tokio::main]
81+
async fn main() -> Result<(), CanoError> {
82+
let counter = Arc::new(TaskCounter::default());
83+
84+
let workflow = Workflow::bare()
85+
.register(Step::Start, DoWork)
86+
.add_exit_state(Step::Done)
87+
.with_observer(counter.clone());
88+
89+
workflow.orchestrate(Step::Start).await?;
90+
assert_eq!(counter.0.load(Ordering::Relaxed), 1);
91+
Ok(())
92+
}
8993
```
9094
<hr class="section-divider">
9195

@@ -213,9 +217,12 @@ impl WorkflowObserver for ChannelObserver {
213217
}
214218
}
215219

216-
let (tx, _rx) = channel();
217-
let observer: std::sync::Arc<dyn WorkflowObserver> =
218-
std::sync::Arc::new(ChannelObserver { tx });
220+
fn main() {
221+
let (tx, _rx) = channel();
222+
let observer: std::sync::Arc<dyn WorkflowObserver> =
223+
std::sync::Arc::new(ChannelObserver { tx });
224+
let _ = observer;
225+
}
219226
```
220227
<hr class="section-divider">
221228

@@ -246,10 +253,16 @@ impl DoWork {
246253
}
247254
}
248255

249-
Workflow::bare()
250-
.register(Step::Start, DoWork)
251-
.add_exit_state(Step::Done)
252-
.with_observer(Arc::new(TracingObserver::new()))
256+
#[tokio::main]
257+
async fn main() -> Result<(), CanoError> {
258+
let workflow = Workflow::bare()
259+
.register(Step::Start, DoWork)
260+
.add_exit_state(Step::Done)
261+
.with_observer(Arc::new(TracingObserver::new()));
262+
263+
workflow.orchestrate(Step::Start).await?;
264+
Ok(())
265+
}
253266
```
254267

255268
<p>It emits <strong>events, not spans</strong> — it does not reproduce the nested span tree the
@@ -322,17 +335,20 @@ checks sequentially.
322335
use cano::prelude::*;
323336

324337
// PrimaryDb and ReadReplica are Resource impls (see ReadReplica above).
325-
let resources: Resources = Resources::new()
326-
.insert("db", PrimaryDb)
327-
.insert("replica", ReadReplica);
328-
329-
for (key, status) in resources.check_all_health().await {
330-
println!("{key}: {status:?}");
331-
}
338+
#[tokio::main]
339+
async fn main() {
340+
let resources: Resources = Resources::new()
341+
.insert("db", PrimaryDb)
342+
.insert("replica", ReadReplica);
343+
344+
for (key, status) in resources.check_all_health().await {
345+
println!("{key}: {status:?}");
346+
}
332347

333-
match resources.aggregate_health().await {
334-
HealthStatus::Healthy => println!("all good"),
335-
other => println!("attention needed: {other:?}"),
348+
match resources.aggregate_health().await {
349+
HealthStatus::Healthy => println!("all good"),
350+
other => println!("attention needed: {other:?}"),
351+
}
336352
}
337353
```
338354

@@ -395,14 +411,18 @@ impl FlakyLoad {
395411
}
396412
}
397413

398-
let observer = Arc::new(PrintingObserver::default());
414+
#[tokio::main]
415+
async fn main() -> Result<(), CanoError> {
416+
let observer = Arc::new(PrintingObserver::default());
399417

400-
let workflow = Workflow::bare()
401-
.register(Step::Load, FlakyLoad { remaining_failures: Arc::new(AtomicUsize::new(2)) })
402-
.add_exit_state(Step::Done)
403-
.with_observer(observer.clone());
418+
let workflow = Workflow::bare()
419+
.register(Step::Load, FlakyLoad { remaining_failures: Arc::new(AtomicUsize::new(2)) })
420+
.add_exit_state(Step::Done)
421+
.with_observer(observer.clone());
404422

405-
workflow.orchestrate(Step::Load).await?;
406-
assert_eq!(observer.failures.load(Ordering::Relaxed), 0);
423+
workflow.orchestrate(Step::Load).await?;
424+
assert_eq!(observer.failures.load(Ordering::Relaxed), 0);
425+
Ok(())
426+
}
407427
```
408428
</div>

docs/content/recovery/_index.md

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,20 @@ impl WorkTask {
7474
}
7575
}
7676

77-
let checkpoint_store = Arc::new(RedbCheckpointStore::new("workflow.redb")?);
78-
79-
let workflow = Workflow::bare()
80-
.register(Step::Start, StartTask)
81-
.register(Step::Work, WorkTask)
82-
.add_exit_state(Step::Done)
83-
.with_checkpoint_store(checkpoint_store)
84-
.with_workflow_id("run-42");
85-
86-
workflow.orchestrate(Step::Start).await?;
77+
#[tokio::main]
78+
async fn main() -> Result<(), CanoError> {
79+
let checkpoint_store = Arc::new(RedbCheckpointStore::new("workflow.redb")?);
80+
81+
let workflow = Workflow::bare()
82+
.register(Step::Start, StartTask)
83+
.register(Step::Work, WorkTask)
84+
.add_exit_state(Step::Done)
85+
.with_checkpoint_store(checkpoint_store)
86+
.with_workflow_id("run-42");
87+
88+
workflow.orchestrate(Step::Start).await?;
89+
Ok(())
90+
}
8791
```
8892
<hr class="section-divider">
8993

@@ -161,16 +165,20 @@ use cano::prelude::*;
161165
use cano::RedbCheckpointStore;
162166
use std::sync::Arc;
163167

164-
let checkpoint_store = Arc::new(RedbCheckpointStore::new("workflow.redb")?);
165-
let workflow = Workflow::bare()
166-
.register(Step::Start, StartTask)
167-
.register(Step::Work, WorkTask)
168-
.add_exit_state(Step::Done)
169-
.with_checkpoint_store(checkpoint_store);
170-
171-
// Some earlier process crashed mid-run; pick up where it left off.
172-
let final_state = workflow.resume_from("run-42").await?;
173-
assert_eq!(final_state, Step::Done);
168+
#[tokio::main]
169+
async fn main() -> Result<(), CanoError> {
170+
let checkpoint_store = Arc::new(RedbCheckpointStore::new("workflow.redb")?);
171+
let workflow = Workflow::bare()
172+
.register(Step::Start, StartTask)
173+
.register(Step::Work, WorkTask)
174+
.add_exit_state(Step::Done)
175+
.with_checkpoint_store(checkpoint_store);
176+
177+
// Some earlier process crashed mid-run; pick up where it left off.
178+
let final_state = workflow.resume_from("run-42").await?;
179+
assert_eq!(final_state, Step::Done);
180+
Ok(())
181+
}
174182
```
175183

176184
<p>
@@ -414,27 +422,31 @@ impl FinalizeTask {
414422
}
415423
}
416424

417-
let checkpoint_store = Arc::new(RedbCheckpointStore::new("recovery.redb")?);
418-
let resources = Resources::new().insert("crash", CrashOnce::default());
419-
let workflow = Workflow::new(resources)
420-
.register(Step::Start, StartTask)
421-
.register(Step::Process, ProcessTask)
422-
.register(Step::Finalize, FinalizeTask)
423-
.add_exit_state(Step::Done)
424-
.with_checkpoint_store(checkpoint_store.clone())
425-
.with_workflow_id("demo-run");
426-
427-
// Run 1: crashes inside ProcessTask. The Start and Process rows are already durable.
428-
let _ = workflow.orchestrate(Step::Start).await;
429-
430-
// Run 2: resume — re-runs ProcessTask (now it succeeds) and finishes at Done.
431-
let final_state = workflow.resume_from("demo-run").await?;
432-
assert_eq!(final_state, Step::Done);
433-
434-
// The append-only log: Start, Process (crash), Process (re-run), Finalize, Done —
435-
// all RowKind::StateEntry here, since this workflow has no compensatable or stepped states.
436-
for row in checkpoint_store.load_run("demo-run").await? {
437-
println!("#{} {:?} {} {}", row.sequence, row.kind, row.state, row.task_id);
425+
#[tokio::main]
426+
async fn main() -> Result<(), CanoError> {
427+
let checkpoint_store = Arc::new(RedbCheckpointStore::new("recovery.redb")?);
428+
let resources = Resources::new().insert("crash", CrashOnce::default());
429+
let workflow = Workflow::new(resources)
430+
.register(Step::Start, StartTask)
431+
.register(Step::Process, ProcessTask)
432+
.register(Step::Finalize, FinalizeTask)
433+
.add_exit_state(Step::Done)
434+
.with_checkpoint_store(checkpoint_store.clone())
435+
.with_workflow_id("demo-run");
436+
437+
// Run 1: crashes inside ProcessTask. The Start and Process rows are already durable.
438+
let _ = workflow.orchestrate(Step::Start).await;
439+
440+
// Run 2: resume — re-runs ProcessTask (now it succeeds) and finishes at Done.
441+
let final_state = workflow.resume_from("demo-run").await?;
442+
assert_eq!(final_state, Step::Done);
443+
444+
// The append-only log: Start, Process (crash), Process (re-run), Finalize, Done —
445+
// all RowKind::StateEntry here, since this workflow has no compensatable or stepped states.
446+
for row in checkpoint_store.load_run("demo-run").await? {
447+
println!("#{} {:?} {} {}", row.sequence, row.kind, row.state, row.task_id);
448+
}
449+
Ok(())
438450
}
439451
```
440452
</div>

docs/content/saga/_index.md

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,16 +316,19 @@ impl ShipOrder {
316316
}
317317
}
318318

319-
let workflow = Workflow::bare()
320-
.register_with_compensation(Step::Reserve, ReserveInventory)
321-
.register(Step::Validate, ValidateOrder) // plain — no compensation
322-
.register_with_compensation(Step::Charge, ChargeCard)
323-
.register(Step::Ship, ShipOrder) // plain — and it fails
324-
.add_exit_state(Step::Done);
325-
326-
match workflow.orchestrate(Step::Reserve).await {
327-
Ok(state) => println!("completed at {state:?}"),
328-
Err(error) => println!("failed, rolled back: {error}"), // "courier unavailable" — the original error
319+
#[tokio::main]
320+
async fn main() {
321+
let workflow = Workflow::bare()
322+
.register_with_compensation(Step::Reserve, ReserveInventory)
323+
.register(Step::Validate, ValidateOrder) // plain — no compensation
324+
.register_with_compensation(Step::Charge, ChargeCard)
325+
.register(Step::Ship, ShipOrder) // plain — and it fails
326+
.add_exit_state(Step::Done);
327+
328+
match workflow.orchestrate(Step::Reserve).await {
329+
Ok(state) => println!("completed at {state:?}"),
330+
Err(error) => println!("failed, rolled back: {error}"), // "courier unavailable" — the original error
331+
}
329332
}
330333
```
331334
</div>

0 commit comments

Comments
 (0)