1use std::fmt;
16use std::fmt::{Display, Formatter};
17use std::str::FromStr;
18
19pub mod bindings {
20 use wit_bindgen::generate;
21
22 generate!({
23 path: "wit",
24 world: "golem-rust",
25 generate_all,
26 generate_unused_types: true,
27 pub_export_macro: true,
28 with: {
29 "golem:rpc/types@0.2.1": golem_wasm_rpc::golem_rpc_0_2_x::types,
30 "wasi:io/poll@0.2.3": golem_wasm_rpc::wasi::io::poll,
31 "wasi:clocks/wall-clock@0.2.3": golem_wasm_rpc::wasi::clocks::wall_clock
32 }
33 });
34}
35
36#[cfg(feature = "export_load_snapshot")]
37pub mod load_snapshot {
38 use wit_bindgen::generate;
39
40 generate!({
41 path: "wit",
42 world: "golem-rust-load-snapshot",
43 generate_all,
44 generate_unused_types: true,
45 pub_export_macro: true,
46 with: {
47 "golem:rpc/types@0.2.1": golem_wasm_rpc::golem_rpc_0_2_x::types,
48 "wasi:io/poll@0.2.3": golem_wasm_rpc::wasi::io::poll,
49 "wasi:clocks/wall-clock@0.2.3": golem_wasm_rpc::wasi::clocks::wall_clock,
50
51 "golem:api/host@1.1.7": crate::bindings::golem::api::host,
52 "golem:api/oplog@1.1.7": crate::bindings::golem::api::oplog,
53 "golem:api/context@1.1.7": crate::bindings::golem::api::context,
54 "golem:durability/durability@1.2.1": crate::bindings::golem::durability::durability,
55 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
56 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
57 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
58 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
59 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
60 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
61 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
62 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
63 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
64 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
65 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
66 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
67 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
68 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
69 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
70 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
71 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
72 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
73 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
74 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
75 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
76 }
77 });
78
79 pub use __export_golem_rust_load_snapshot_impl as export_load_snapshot;
80}
81
82#[cfg(feature = "export_save_snapshot")]
83pub mod save_snapshot {
84 use wit_bindgen::generate;
85
86 generate!({
87 path: "wit",
88 world: "golem-rust-save-snapshot",
89 generate_all,
90 generate_unused_types: true,
91 pub_export_macro: true,
92 with: {
93 "golem:rpc/types@0.2.1": golem_wasm_rpc::golem_rpc_0_2_x::types,
94 "wasi:io/poll@0.2.3": golem_wasm_rpc::wasi::io::poll,
95 "wasi:clocks/wall-clock@0.2.3": golem_wasm_rpc::wasi::clocks::wall_clock,
96
97 "golem:api/host@1.1.7": crate::bindings::golem::api::host,
98 "golem:api/oplog@1.1.7": crate::bindings::golem::api::oplog,
99 "golem:api/context@1.1.7": crate::bindings::golem::api::context,
100 "golem:durability/durability@1.2.1": crate::bindings::golem::durability::durability,
101 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
102 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
103 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
104 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
105 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
106 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
107 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
108 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
109 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
110 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
111 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
112 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
113 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
114 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
115 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
116 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
117 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
118 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
119 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
120 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
121 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
122 }
123 });
124
125 pub use __export_golem_rust_save_snapshot_impl as export_save_snapshot;
126}
127
128#[cfg(feature = "export_oplog_processor")]
129pub mod oplog_processor {
130 use wit_bindgen::generate;
131
132 generate!({
133 path: "wit",
134 world: "golem-rust-oplog-processor",
135 generate_all,
136 generate_unused_types: true,
137 pub_export_macro: true,
138 with: {
139 "golem:rpc/types@0.2.1": golem_wasm_rpc::golem_rpc_0_2_x::types,
140 "wasi:io/poll@0.2.3": golem_wasm_rpc::wasi::io::poll,
141 "wasi:clocks/wall-clock@0.2.3": golem_wasm_rpc::wasi::clocks::wall_clock,
142
143 "golem:api/host@1.1.7": crate::bindings::golem::api::host,
144 "golem:api/oplog@1.1.7": crate::bindings::golem::api::oplog,
145 "golem:api/context@1.1.7": crate::bindings::golem::api::context,
146 "golem:durability/durability@1.2.1": crate::bindings::golem::durability::durability,
147 "golem:rdbms/mysql@0.0.1": crate::bindings::golem::rdbms::mysql,
148 "golem:rdbms/postgres@0.0.1": crate::bindings::golem::rdbms::postgres,
149 "golem:rdbms/types@0.0.1": crate::bindings::golem::rdbms::types,
150 "wasi:blobstore/blobstore": crate::bindings::wasi::blobstore::blobstore,
151 "wasi:blobstore/container": crate::bindings::wasi::blobstore::container,
152 "wasi:blobstore/types": crate::bindings::wasi::blobstore::types,
153 "wasi:clocks/monotonic-clock@0.2.3": crate::bindings::wasi::clocks::monotonic_clock,
154 "wasi:filesystem/preopens@0.2.3": crate::bindings::wasi::filesystem::preopens,
155 "wasi:filesystem/types@0.2.3": crate::bindings::wasi::filesystem::types,
156 "wasi:http/types@0.2.3": crate::bindings::wasi::http::types,
157 "wasi:http/outgoing-handler@0.2.3": crate::bindings::wasi::http::outgoing_handler,
158 "wasi:io/error@0.2.3": crate::bindings::wasi::io::error,
159 "wasi:io/streams@0.2.3": crate::bindings::wasi::io::streams,
160 "wasi:keyvalue/eventual-batch@0.1.0": crate::bindings::wasi::keyvalue::eventual_batch,
161 "wasi:keyvalue/eventual@0.1.0": crate::bindings::wasi::keyvalue::eventual,
162 "wasi:keyvalue/types@0.1.0": crate::bindings::wasi::keyvalue::types,
163 "wasi:keyvalue/wasi-keyvalue-error@0.1.0": crate::bindings::wasi::keyvalue::wasi_keyvalue_error,
164 "wasi:logging/logging": crate::bindings::wasi::logging::logging,
165 "wasi:sockets/ip-name-lookup@0.2.3": crate::bindings::wasi::sockets::ip_name_lookup,
166 "wasi:sockets/instance-network@0.2.3": crate::bindings::wasi::sockets::instance_network,
167 "wasi:sockets/network@0.2.3": crate::bindings::wasi::sockets::network,
168 }
169 });
170
171 pub use __export_golem_rust_oplog_processor_impl as export_oplog_processor;
172}
173
174#[cfg(feature = "durability")]
175pub mod durability;
176
177#[cfg(feature = "json")]
178mod json;
179
180#[cfg(feature = "json")]
181pub use json::*;
182
183mod transaction;
184pub mod value_and_type;
185
186use bindings::golem::api::host::*;
187
188pub use golem_wasm_rpc as wasm_rpc;
189
190pub use bindings::golem::api::host::{fork, oplog_commit};
191pub use bindings::golem::api::host::{ForkResult, PersistenceLevel};
192
193pub use transaction::*;
194
195#[cfg(feature = "macro")]
196pub use golem_rust_macro::*;
197
198impl Display for PromiseId {
199 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
200 write!(f, "{}/{}", self.worker_id, self.oplog_idx)
201 }
202}
203
204impl FromStr for PromiseId {
205 type Err = String;
206
207 fn from_str(s: &str) -> Result<Self, Self::Err> {
208 let parts: Vec<&str> = s.split('/').collect();
209 if parts.len() == 2 {
210 let worker_id = WorkerId::from_str(parts[0]).map_err(|_| {
211 format!("invalid worker id: {s} - expected format: <component_id>/<worker_name>")
212 })?;
213 let oplog_idx = parts[1]
214 .parse()
215 .map_err(|_| format!("invalid oplog index: {s} - expected integer"))?;
216 Ok(Self {
217 worker_id,
218 oplog_idx,
219 })
220 } else {
221 Err(format!(
222 "invalid promise id: {s} - expected format: <worker_id>/<oplog_idx>"
223 ))
224 }
225 }
226}
227
228#[derive(Clone, Debug, PartialEq)]
229pub struct RetryPolicy {
230 pub max_attempts: u32,
231 pub min_delay: std::time::Duration,
232 pub max_delay: std::time::Duration,
233 pub multiplier: f64,
234 pub max_jitter_factor: Option<f64>,
235}
236
237impl From<bindings::golem::api::host::RetryPolicy> for RetryPolicy {
238 fn from(value: bindings::golem::api::host::RetryPolicy) -> Self {
239 Self {
240 max_attempts: value.max_attempts,
241 min_delay: std::time::Duration::from_nanos(value.min_delay),
242 max_delay: std::time::Duration::from_nanos(value.max_delay),
243 multiplier: value.multiplier,
244 max_jitter_factor: value.max_jitter_factor,
245 }
246 }
247}
248
249impl From<RetryPolicy> for bindings::golem::api::host::RetryPolicy {
250 fn from(val: RetryPolicy) -> Self {
251 bindings::golem::api::host::RetryPolicy {
252 max_attempts: val.max_attempts,
253 min_delay: val.min_delay.as_nanos() as u64,
254 max_delay: val.max_delay.as_nanos() as u64,
255 multiplier: val.multiplier,
256 max_jitter_factor: val.max_jitter_factor,
257 }
258 }
259}
260
261pub struct PersistenceLevelGuard {
262 original_level: PersistenceLevel,
263}
264
265impl Drop for PersistenceLevelGuard {
266 fn drop(&mut self) {
267 set_oplog_persistence_level(self.original_level);
268 }
269}
270
271#[must_use]
275pub fn use_persistence_level(level: PersistenceLevel) -> PersistenceLevelGuard {
276 let original_level = get_oplog_persistence_level();
277 set_oplog_persistence_level(level);
278 PersistenceLevelGuard { original_level }
279}
280
281pub fn with_persistence_level<R>(level: PersistenceLevel, f: impl FnOnce() -> R) -> R {
283 let _guard = use_persistence_level(level);
284 f()
285}
286
287pub struct IdempotenceModeGuard {
288 original: bool,
289}
290
291impl Drop for IdempotenceModeGuard {
292 fn drop(&mut self) {
293 set_idempotence_mode(self.original);
294 }
295}
296
297#[must_use]
301pub fn use_idempotence_mode(mode: bool) -> IdempotenceModeGuard {
302 let original = get_idempotence_mode();
303 set_idempotence_mode(mode);
304 IdempotenceModeGuard { original }
305}
306
307pub fn with_idempotence_mode<R>(mode: bool, f: impl FnOnce() -> R) -> R {
309 let _guard = use_idempotence_mode(mode);
310 f()
311}
312
313pub fn generate_idempotency_key() -> uuid::Uuid {
317 Into::into(bindings::golem::api::host::generate_idempotency_key())
318}
319
320pub struct RetryPolicyGuard {
321 original: RetryPolicy,
322}
323
324impl Drop for RetryPolicyGuard {
325 fn drop(&mut self) {
326 set_retry_policy(Into::into(self.original.clone()));
327 }
328}
329
330#[must_use]
334pub fn use_retry_policy(policy: RetryPolicy) -> RetryPolicyGuard {
335 let original = Into::into(get_retry_policy());
336 set_retry_policy(Into::into(policy));
337 RetryPolicyGuard { original }
338}
339
340pub fn with_retry_policy<R>(policy: RetryPolicy, f: impl FnOnce() -> R) -> R {
342 let _guard = use_retry_policy(policy);
343 f()
344}
345
346pub struct AtomicOperationGuard {
347 begin: OplogIndex,
348}
349
350impl Drop for AtomicOperationGuard {
351 fn drop(&mut self) {
352 mark_end_operation(self.begin);
353 }
354}
355
356#[must_use]
361pub fn mark_atomic_operation() -> AtomicOperationGuard {
362 let begin = mark_begin_operation();
363 AtomicOperationGuard { begin }
364}
365
366pub fn atomically<T>(f: impl FnOnce() -> T) -> T {
370 let _guard = mark_atomic_operation();
371 f()
372}