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
use std::{
time::Duration,
vec::*,
};
use ferrite_session::prelude::*;
use tokio::time::sleep;
pub fn concat_session() -> Session<End>
{
let p1: Session<
ReceiveValue<
Vec<String>,
ReceiveValue<Vec<String>, SendValue<String, End>>,
>,
> = receive_value(|l1: Vec<String>| {
println!("[P1] Received first list: [{}]", l1.join(", "));
receive_value(|l2: Vec<String>| {
println!("[P1] Received second list: [{}]", l2.join(", "));
step(async move {
send_value(
{
println!("[P1] Spending 3 seconds to concat lists");
sleep(Duration::from_secs(3)).await;
let l5 = {
let mut l3 = l1;
let mut l4 = l2;
l3.append(&mut l4);
l3
};
l5.join(", ")
},
terminate_async(|| async {
println!("[P1] Spending 2 seconds to cleanup");
sleep(Duration::from_secs(2)).await;
println!("[P1] Terminating");
}),
)
})
})
});
let p2: Session<
ReceiveChannel<
ReceiveValue<
Vec<String>,
ReceiveValue<Vec<String>, SendValue<String, End>>,
>,
End,
>,
> = receive_channel(|val_chan| {
step(async move {
send_value_to(
val_chan,
{
println!("[P2] spending 2 seconds to produce ['hello', 'world']");
sleep(Duration::from_secs(2)).await;
vec!["hello".to_string(), "world".to_string()]
},
step(async move {
send_value_to(
val_chan,
{
println!(
"[P2] spending 1 second to produce ['foo', 'bar', 'baz']"
);
sleep(Duration::from_secs(1)).await;
vec!["foo".to_string(), "bar".to_string(), "baz".to_string()]
},
receive_value_from(val_chan, move |res| {
println!("[P2] received result from P1: [{}]", res);
wait(val_chan, {
println!("[P2] P1 has terminated");
terminate_async(|| async {
println!("[P2] Spending 1 second to cleanup");
sleep(Duration::from_secs(1)).await;
println!("[P2] Terminating");
})
})
}),
)
}),
)
})
});
apply_channel(p2, p1)
}
#[tokio::main]
pub async fn main()
{
run_session(concat_session()).await;
}