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
use flowync::{error::Cause, Flower};
use std::{
io::Error,
time::{Duration, Instant},
};
type TestVectoredFlower = Flower<String, u32>;
fn main() {
let instant: Instant = Instant::now();
let mut vec_opt_flowers = Vec::new();
for i in 0..5 {
let flower: TestVectoredFlower = Flower::new(i);
std::thread::spawn({
let this = flower.handle();
// Activate if need too, actually needless on this context because we use Option
// this.activate();
move || {
let id = this.id();
// Panic if need to.
// if id == 3 {
// std::panic::panic_any("loudness");
// }
let millis = id + 1;
let sleep_dur = Duration::from_millis((10 * millis) as u64);
std::thread::sleep(sleep_dur);
let result =
Ok::<String, Error>(format!("the flower with id: {} wake up from sleep", id));
match result {
Ok(value) => {
// Send current flower progress.
this.send(value);
}
Err(e) => {
// Return error immediately if something not right, for example:
return this.error_verbose(e.into());
}
}
// Explicit cancelation example:
// Check if the current flower should be canceled
if this.should_cancel() {
let value = format!("canceling the flower with id: {}", id);
this.send(value);
return this.error(format!("the flower with id: {} canceled", id));
}
// Finishing
// either return this.ok(instant.elapsed().subsec_millis()); or
this.success(instant.elapsed().subsec_millis());
// both are ok
}
});
vec_opt_flowers.push(Some(flower));
}
let num_flowers = vec_opt_flowers.len();
let mut count_down = num_flowers;
loop {
vec_opt_flowers.iter_mut().for_each(|opt_flower| {
if let Some(flower) = opt_flower {
let id = flower.id();
// Cancel if need to.
// if (id % 2 != 0) || (id == 0) {
// flower.cancel();
// }
let mut done = false;
flower
.extract(|value| println!("{}", value))
.finalize(|result| {
match result {
Ok(elapsed) => println!(
"the flower with id: {} finished in: {:?} milliseconds\n",
id, elapsed
),
Err(Cause::Suppose(msg)) => {
println!("{}", msg)
}
Err(Cause::Panicked(msg)) => {
println!("{}", msg)
}
}
done = true;
});
if done {
// Set to None to free later
*opt_flower = None;
count_down -= 1;
}
}
});
if count_down == 0 {
// Free completed flower
vec_opt_flowers = vec_opt_flowers
.into_iter()
.filter(|opt_flower| opt_flower.is_some())
.collect::<Vec<_>>();
println!(
"finished with vec_opt_flowers remains: {}",
vec_opt_flowers.len()
);
break;
}
}
}