Created
June 7, 2019 19:10
-
-
Save csherratt/b38cda9160af26334e3ae9369efced37 to your computer and use it in GitHub Desktop.
Actors take II
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Actor<T> { | |
pub fn new(inner: T, pool: &Pool) -> Actor<T>; | |
pub fn sync<U>(&self, msg: FnOnce(&mut T)) -> U; | |
pub fn async<U>(&self, msg: FnOnce(&mut T)) -> Future<U>; | |
} | |
fn example() { | |
// wake the main thread and create an actor on it | |
let button = main_pool.sync( | |
|pool| Actor::new(Button::new(), pool) | |
); | |
// an actor handle can be cloned, and the actors life cycle is tied | |
// the existance of these handles. When a handle dies, the actor is released. | |
let sent_button = button.clone(); | |
thread::spawn(move || { | |
// the handle is Send even if the actor's inner body is not. Meaning it can live | |
// on other thread and safely talk to the actor if they choose to. | |
let old_color = sent_button.sync(|button| { | |
// we can talk to the button on the main thread, a sync block blocks the current | |
// thread until the message is reponded to. But has the advantage of being simpler | |
// and avoiding allocation that is required by a Box<FnOnce> | |
let old_color = button.color(); | |
button.set_color(Color.red); | |
// data can be sent back if we choose to. This can help us fairy data too and from the actor | |
old_color | |
}); | |
// we can also async send to the actor, meaning it needn't block. These are handled | |
// as soon as possible by the main thread, but may need to wait for other IO to complete. | |
let some_future = sent_button.async(|button| { | |
button.set_color(old_color); | |
// it could be nice to self enqueue, since this is run in locked actor context | |
// we can do a faster job of doing an async enqueue. | |
after(|button| { | |
}); | |
// also enqueue to the end of the queue, avoiding the fast path. Useful if you want | |
// fair handling of actions. | |
later(|button| { | |
}); | |
// The API of those two are probably not possible, they will likely require a `Context` object | |
// that will convay the types. | |
}); | |
}) | |
// It's important to point out that the locking model means only one function is every being | |
// applied to the object. | |
button.async(|button| { | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment