pub struct Actor<T> { /* private fields */ }Expand description
coroutine based Actor.
The type Actor<T> wraps T into an Actor.
You can send message to the actor by calling it’s call method.
You can run a closure synchronously with the actor internal state by calling it’s with method.
§Examples
use may_actor::Actor;
let a = Actor::new(40);
a.call(|me| *me += 2);
a.with(|me| assert_eq!(*me, 42));Implementations§
Source§impl<T> Actor<T>
impl<T> Actor<T>
Sourcepub fn new(actor: T) -> Self
pub fn new(actor: T) -> Self
create an actor by consuming the actual actor implementation
Examples found in repository?
More examples
55fn pi_actor() -> f64 {
56 const WORKS: usize = TOTAL_NUM / WORK_LOAD;
57
58 struct Worker;
59 impl Worker {
60 fn work(&self, master: Actor<Master>, start: usize, end: usize) {
61 let data = calc_work(start, end);
62 master.call(move |me| me.recv_data(data));
63 }
64 }
65
66 struct Master {
67 pi: f64,
68 count: usize,
69 tx: mpsc::Sender<f64>,
70 }
71
72 impl Master {
73 fn start(&self) {
74 // create the worker actors
75 let mut workers = Vec::with_capacity(ACTOR_NUMBER);
76 for _ in 0..ACTOR_NUMBER {
77 workers.push(Actor::new(Worker));
78 }
79
80 // send work load to workers
81 let mut start = 0;
82 for i in 0..WORKS {
83 let end = start + WORK_LOAD;
84 let master = unsafe { Actor::from(self) };
85 workers[i % ACTOR_NUMBER].call(move |me| me.work(master, start, end));
86 start = end;
87 }
88 }
89
90 fn recv_data(&mut self, data: f64) {
91 self.pi += data;
92 self.count += 1;
93 if self.count == WORKS {
94 self.tx.send(self.pi).unwrap();
95 }
96 }
97 }
98
99 let (tx, rx) = mpsc::channel();
100
101 // create the master actor
102 let master = Actor::new(Master {
103 pi: 0.0,
104 count: 0,
105 tx: tx,
106 });
107
108 master.call(|me| me.start());
109
110 rx.recv().unwrap() * 4.0
111}Sourcepub fn drive_new<F>(data: T, f: F) -> Self
pub fn drive_new<F>(data: T, f: F) -> Self
create an actor with a driver coroutine running in background when all actor instances got dropped, the driver coroutine would be cancelled
Sourcepub unsafe fn from(inner: &T) -> Self
pub unsafe fn from(inner: &T) -> Self
convert from inner ref to actor
§Safety
only valid if &Tis coming from an actor.
normally this is used to convert &self to Actor<T>
Examples found in repository?
73 fn start(&self) {
74 // create the worker actors
75 let mut workers = Vec::with_capacity(ACTOR_NUMBER);
76 for _ in 0..ACTOR_NUMBER {
77 workers.push(Actor::new(Worker));
78 }
79
80 // send work load to workers
81 let mut start = 0;
82 for i in 0..WORKS {
83 let end = start + WORK_LOAD;
84 let master = unsafe { Actor::from(self) };
85 workers[i % ACTOR_NUMBER].call(move |me| me.work(master, start, end));
86 start = end;
87 }
88 }Sourcepub fn call<F>(&self, f: F)
pub fn call<F>(&self, f: F)
send the actor a ‘message’ by a closure.
the closure would get the &mut T as parameter,
so that you can manipulate its internal state.
the raw actor type must be Send and 'static
so that it can be used by multi threads.
the closure would be executed asynchronously
Examples found in repository?
55fn pi_actor() -> f64 {
56 const WORKS: usize = TOTAL_NUM / WORK_LOAD;
57
58 struct Worker;
59 impl Worker {
60 fn work(&self, master: Actor<Master>, start: usize, end: usize) {
61 let data = calc_work(start, end);
62 master.call(move |me| me.recv_data(data));
63 }
64 }
65
66 struct Master {
67 pi: f64,
68 count: usize,
69 tx: mpsc::Sender<f64>,
70 }
71
72 impl Master {
73 fn start(&self) {
74 // create the worker actors
75 let mut workers = Vec::with_capacity(ACTOR_NUMBER);
76 for _ in 0..ACTOR_NUMBER {
77 workers.push(Actor::new(Worker));
78 }
79
80 // send work load to workers
81 let mut start = 0;
82 for i in 0..WORKS {
83 let end = start + WORK_LOAD;
84 let master = unsafe { Actor::from(self) };
85 workers[i % ACTOR_NUMBER].call(move |me| me.work(master, start, end));
86 start = end;
87 }
88 }
89
90 fn recv_data(&mut self, data: f64) {
91 self.pi += data;
92 self.count += 1;
93 if self.count == WORKS {
94 self.tx.send(self.pi).unwrap();
95 }
96 }
97 }
98
99 let (tx, rx) = mpsc::channel();
100
101 // create the master actor
102 let master = Actor::new(Master {
103 pi: 0.0,
104 count: 0,
105 tx: tx,
106 });
107
108 master.call(|me| me.start());
109
110 rx.recv().unwrap() * 4.0
111}