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
//! Defines the `NonDet` type and `nondet!` macro for tracking non-determinism.
//!
//! All **safe** APIs in Hydro guarantee determinism, even in the face of networking delays
//! and concurrency across machines. But often it is necessary to do something non-deterministic,
//! like generate events at a fixed wall-clock-time interval, or split an input into arbitrarily
//! sized batches.
//!
//! These non-deterministic APIs take additional parameters called **non-determinism guards**.
//! These values, with type `NonDet`, help you reason about how non-determinism affects your
//! application. To pass a non-determinism guard, you must invoke `nondet!()` with an explanation
//! for how the non-determinism affects the application.
//!
//! See the [Hydro docs](https://hydro.run/docs/hydro/reference/live-collections/determinism) for more.
/// A non-determinism guard, which documents how a source of non-determinism affects the application.
///
/// To create a non-determinism guard, use the [`nondet!`] macro, which takes in a doc comment
/// explaining the effects of the particular source of non-determinism, and additional
/// non-determinism guards that justify the form of non-determinism.
;
pub use crate__nondet__ as nondet;
/// Fulfills a non-determinism guard parameter by declaring a reason why the
/// non-determinism is tolerated or providing other non-determinism guards
/// that forward the inner non-determinism.
///
/// The first argument must be a doc comment with the reason the non-determinism
/// is okay. If forwarding a parent non-determinism, because the non-determinism
/// is not handled internally, you should provide a short explanation of how the
/// inner non-determinism is captured by the outer one. If the non-determinism
/// is locally resolved, you should document _why_ this is the case.
///
/// # Examples
/// Locally resolved non-determinism:
/// ```rust,no_run
/// # use hydro_lang::prelude::*;
/// use std::time::Duration;
///
/// fn singleton_with_delay<T, L>(
/// singleton: Singleton<T, Process<L>, Unbounded>
/// ) -> Optional<T, Process<L>, Unbounded> {
/// singleton
/// .sample_every(q!(Duration::from_secs(1)), nondet!(/**
/// non-deterministic samples will eventually resolve to stable result
/// */))
/// .last()
/// }
/// ```
///
/// Forwarded non-determinism:
/// ```rust
/// # use hydro_lang::prelude::*;
/// use hydro_lang::live_collections::stream::ExactlyOnce;
///
/// use std::fmt::Debug;
/// use std::time::Duration;
///
/// /// ...
/// ///
/// /// # Non-Determinism
/// /// - `nondet_samples`: this function will non-deterministically print elements
/// /// from the stream according to a timer
/// fn print_samples<T: Debug, L>(
/// stream: Stream<T, Process<L>, Unbounded>,
/// nondet_samples: NonDet
/// ) {
/// stream
/// .sample_every(q!(Duration::from_secs(1)), nondet!(
/// /// non-deterministic timing will result in non-determistic samples printed
/// nondet_samples
/// ))
/// .assume_retries::<ExactlyOnce>(nondet!(
/// /// non-deterministic duplicated logs are okay
/// nondet_samples
/// ))
/// .for_each(q!(|v| println!("Sample: {:?}", v)))
/// }
/// ```