-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathactor.rs
More file actions
124 lines (116 loc) · 4.15 KB
/
Copy pathactor.rs
File metadata and controls
124 lines (116 loc) · 4.15 KB
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
114
115
116
117
118
119
120
121
122
123
124
use std::collections::HashMap;
use std::thread;
use std::time::{Duration, Instant};
use fp_rust::actor::{Actor, ActorAsync, Handle};
use fp_rust::common::{LinkedListAsync, UniqueId};
#[derive(Clone, Debug)]
enum Value {
Int(i32),
VecStr(Vec<String>),
Spawn,
Shutdown,
}
fn main() {
let result_i32 = LinkedListAsync::<i32>::new();
let result_i32_thread = result_i32.clone();
let result_string = LinkedListAsync::<Vec<String>>::new();
let result_string_thread = result_string.clone();
let mut root = ActorAsync::new(
move |this: &mut ActorAsync<_, _>, msg: Value, context: &mut HashMap<String, Value>| {
match msg {
Value::Spawn => {
println!("Actor Spawn");
let result_i32_thread = result_i32_thread.clone();
let spawned = this.spawn_with_handle(Box::new(
move |this: &mut ActorAsync<_, _>, msg: Value, _| {
match msg {
Value::Int(v) => {
println!("Actor Child Int");
result_i32_thread.push_back(v * 10);
}
Value::Shutdown => {
println!("Actor Child Shutdown");
this.stop();
}
_ => {}
};
},
));
let list = context.get("children_ids").cloned();
let mut list = match list {
Some(Value::VecStr(list)) => list,
_ => Vec::new(),
};
list.push(spawned.get_id());
context.insert("children_ids".into(), Value::VecStr(list));
}
Value::Shutdown => {
println!("Actor Shutdown");
if let Some(Value::VecStr(ids)) = context.get("children_ids") {
result_string_thread.push_back(ids.clone());
}
this.for_each_child(move |id, handle| {
println!("Actor Shutdown id {:?}", id);
handle.send(Value::Shutdown);
});
this.stop();
}
Value::Int(v) => {
println!("Actor Int");
if let Some(Value::VecStr(ids)) = context.get("children_ids") {
for id in ids {
println!("Actor Int id {:?}", id);
if let Some(mut handle) = this.get_handle_child(id) {
handle.send(Value::Int(v));
}
}
}
}
_ => {}
}
},
);
let mut root_handle = root.get_handle();
root.start();
root_handle.send(Value::Spawn);
root_handle.send(Value::Int(10));
root_handle.send(Value::Spawn);
root_handle.send(Value::Int(20));
root_handle.send(Value::Spawn);
root_handle.send(Value::Int(30));
root_handle.send(Value::Shutdown);
let ids_deadline = Instant::now() + Duration::from_secs(5);
let ids = loop {
if let Some(v) = result_string.pop_front() {
break Some(v);
}
if Instant::now() >= ids_deadline {
break None;
}
thread::yield_now();
};
assert_eq!(Some(3), ids.map(|ids| ids.len()));
let mut v = Vec::<Option<i32>>::new();
let v_deadline = Instant::now() + Duration::from_secs(5);
while v.len() < 6 {
if let Some(i) = result_i32.pop_front() {
v.push(Some(i));
} else if Instant::now() >= v_deadline {
break;
} else {
thread::yield_now();
}
}
v.sort();
assert_eq!(
[
Some(100),
Some(200),
Some(200),
Some(300),
Some(300),
Some(300)
],
v.as_slice()
);
}