lace_tokio/operations/
bounded.rs1use super::*;
5
6#[must_use = "run or close the bounded interlace"]
10pub struct BoundedInterlace {
11 pub(crate) driver: DriverCore,
12 observations: Vec<InterlaceEvent>,
13 settling: bool,
15 outcome: Option<BoundedInterlaceOutcome>,
16}
17
18impl BoundedInterlace {
19 pub fn new(
20 first: impl Into<Participant>,
21 second: impl Into<Participant>,
22 policy: impl IntoPolicy,
23 operation: InterlaceOperationOptions,
24 ) -> Result<Self> {
25 let module = policy.into_policy()?;
26 let operands = [module.clone(), module];
27 Ok(Self::owning(route(
28 first.into(),
29 second.into(),
30 operands,
31 operation.limits,
32 )?))
33 }
34
35 pub(super) fn owning(open: OpenInterlace) -> Self {
36 Self {
37 driver: open.driver,
38 observations: Vec::new(),
39 settling: false,
40 outcome: None,
41 }
42 }
43
44 pub async fn run(&mut self) -> BoundedInterlaceOutcome {
47 if let Some(outcome) = &self.outcome {
48 return outcome.clone();
49 }
50 let collected = self.collect(drop).await;
51 let outcome = finish_bounded(collected, None, self.driver.peer_diagnostics());
52 self.outcome = Some(outcome.clone());
53 outcome
54 }
55
56 pub async fn close(self) -> Result<()> {
61 self.driver.close_cancelled().await.map(drop)
62 }
63
64 pub(super) async fn collect(
68 &mut self,
69 mut saved: impl FnMut(Record),
70 ) -> (Vec<InterlaceEvent>, Option<Error>) {
71 let error = loop {
72 if self.settling {
73 let error = Error::integration("bounded route settlement was interrupted");
74 self.driver.fail(error.clone());
75 break Some(error);
76 }
77 match self.driver.next_event().await {
78 Ok(Some(OpenEvent::FixedPoint)) => {
79 self.settling = true;
80 let settled = self.driver.settle_route().await;
81 self.settling = false;
82 match settled {
83 Ok(()) => {
84 self.observations.push(InterlaceEvent::FixedPoint);
85 break None;
86 }
87 Err(error) => break Some(error),
88 }
89 }
90 Ok(Some(OpenEvent::Closed { .. })) | Ok(None) => break Some(exhausted()),
91 Ok(Some(OpenEvent::RecordSaved {
92 position,
93 record_hash,
94 record,
95 })) => {
96 self.observations.push(InterlaceEvent::RecordSaved {
97 position,
98 record_hash,
99 });
100 if position == ParticipantPosition::First {
101 saved(record);
102 }
103 }
104 Ok(Some(event)) => self.observations.push(event.into()),
105 Err(error) => break Some(error),
106 }
107 };
108 (std::mem::take(&mut self.observations), error)
109 }
110}