Last active
April 26, 2021 09:15
-
-
Save huntc/97985c6bf3f138ca35196423ec8801a0 to your computer and use it in GitHub Desktop.
Actor thoughts
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
// Re-creates https://doc.akka.io/docs/akka/current/typed/actors.html#first-example | |
// The messages | |
struct Greet { | |
whom: String, | |
reply_to: ActorRef<Greeted>, | |
} | |
struct Greeted { | |
whom: String, | |
from: ActorRef<Greet>, | |
} | |
struct SayHello { | |
name: String, | |
} | |
// The HelloWorld actor | |
struct HelloWorld {} | |
impl Actor<Greet> for HelloWorld { | |
fn receive(&mut self, context: &mut ActorContext<Greet>, message: &Greet) { | |
println!("Hello {}!", message.whom); | |
message.reply_to.tell(Greeted { | |
whom: message.whom.to_owned(), | |
from: context.actor_ref.to_owned(), | |
}); | |
} | |
} | |
// The HelloWorldBot actor | |
struct HelloWorldBot { | |
greeting_counter: u32, | |
max: u32, | |
} | |
impl Actor<Greeted> for HelloWorldBot { | |
fn receive(&mut self, context: &mut ActorContext<Greeted>, message: &Greeted) { | |
let n = self.greeting_counter + 1; | |
println!("Greeting {} for {}", n, message.whom); | |
if n == self.max { | |
context.stop(); | |
} else { | |
message.from.tell(Greet { | |
whom: message.whom.to_owned(), | |
reply_to: context.actor_ref.to_owned(), | |
}); | |
self.greeting_counter = n; | |
} | |
} | |
} | |
// The root actor | |
struct HelloWorldMain { | |
greeter: Option<ActorRef<Greet>>, | |
} | |
impl Actor<SayHello> for HelloWorldMain { | |
fn receive(&mut self, context: &mut ActorContext<SayHello>, message: &SayHello) { | |
let greeter = match &self.greeter { | |
None => { | |
let greeter = context.spawn(|| Box::new(HelloWorld {}), "greeter"); | |
self.greeter = Some(greeter.to_owned()); | |
greeter | |
} | |
Some(greeter) => greeter.to_owned(), | |
}; | |
let reply_to = context.spawn( | |
|| { | |
Box::new(HelloWorldBot { | |
greeting_counter: 0, | |
max: 3, | |
}) | |
}, | |
&message.name, | |
); | |
greeter.tell(Greet { | |
whom: message.name.to_owned(), | |
reply_to, | |
}); | |
} | |
} | |
// Create a root context, which is essentiallly the actor system. We | |
// also send a couple of messages for our demo. | |
let system = ActorContext::<SayHello>::new( | |
|| Box::new(HelloWorldMain { greeter: None }), | |
"hello", | |
dispatcher.to_owned(), | |
); | |
system.actor_ref.tell(SayHello { | |
name: "World".to_string(), | |
}); | |
system.actor_ref.tell(SayHello { | |
name: "Mylib".to_string(), | |
}); | |
// We create an executor along with a dispatcher so our actors can schedule | |
// their execution. | |
let dispatcher = ... | |
/// I have this bit working, but want to tidy it up - suffice to state, it is designed | |
/// to be adapted for any executor lib. | |
// Run the dispatcher select function on its own thread. We wait | |
// for the select function to finish, which will be when will | |
// tell the "system" (the actor context above) to stop, it is stops | |
// itself. | |
let select_thread_dispatcher = dispatcher.to_owned(); | |
let select_thread = thread::spawn(move || select_thread_dispatcher.select()); | |
thread::sleep(Duration::from_millis(500)); | |
dispatcher.stop(); | |
assert!(select_thread.join().is_ok()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See https://github.com/titanclass/stage for the actual project