1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! # Fusee
//!
//! Durable execution at the speed of the disk. Workflows are ordinary async
//! Rust; each step's result is appended to a per-shard log, one `fdatasync`
//! covers every record that arrived in the meantime, and the next step
//! starts as soon as its input is durable. Code runs ahead of the disk; only
//! work that leaves the process waits, and only for the records it depends
//! on.
//!
//! ```no_run
//! use fusee::{Config, Engine, Error, RetryPolicy, Signal, WorkflowRef};
//! use std::time::Duration;
//!
//! pub const CHECKOUT: WorkflowRef<u64, String> = WorkflowRef::new("checkout");
//! pub const REVIEW: Signal<bool> = Signal::new("review");
//!
//! # async fn charge(cents: u64, key: String) -> Result<String, Error> { Ok(key) }
//! # async fn demo() -> Result<(), Error> {
//! let engine = Engine::open(Config::local("./data")).await?;
//! engine.register(CHECKOUT, |ctx, order: u64| async move {
//! let quote: u64 = ctx.step("quote", || async move { Ok::<_, Error>(order * 2) }).await?;
//! let id: String = ctx
//! .step("charge", || charge(quote, ctx.key()))
//! .retry(RetryPolicy::attempts(5))
//! .await?;
//! match ctx.wait_for(REVIEW).timeout(Duration::from_secs(86_400)).await? {
//! Some(true) => Ok(id),
//! _ => ctx.step("refund", || async { Ok::<_, Error>(String::new()) }).await,
//! }
//! });
//! let run = engine.start(CHECKOUT, "order-123", &21).await?;
//! run.signal(REVIEW, &true).await?;
//! println!("{}", run.result().await?);
//! # Ok(()) }
//! ```
//!
//! Options are builder methods on the operation, then `.await`: a step's
//! `.retry(..)`, `.timeout(..)`, `.read_only()`, `.limit(..)`; a wait's
//! `.timeout(..)`; a start's `.id_policy(..)`, `.timeout(..)`; an update's
//! or call's `.id(..)`. A step's error is anything that converts into a
//! [`Failure`] (every error type does); return [`Failure::fatal`] to fail
//! without retries.
//!
//! ## Guarantees
//!
//! - An acknowledged start, signal or step result is never lost within the
//! durability mode's failure model.
//! - A recorded step result never changes, and code after it sees the same
//! value on every run.
//! - A step's function runs at least once. It runs again only if the
//! process failed before that step's result became durable.
//! [`Ctx::key`] returns a stable key; pass it to services that accept
//! idempotency keys to make the effect exactly once.
//! - Nothing leaves the process based on state a crash could take back.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
/// Spin-then-park budgets, shared with the replication I/O thread.
/// For the bindings and the server; not part of the documented interface.
/// For the bindings and the server; not part of the documented interface.
pub use ;
pub use ;
pub use ;
pub use Profile;
pub use ;
pub use ;
pub use ;
pub use ;
pub use fusee_core as core;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;