Open DAOCUONG opened 4 years ago
If you infinitly loop inside an actor, you block one thread of the threadpool. If you infinitly loop in more actors than there are threads in the threadpool, the system hangs because it can't process any other messages. So it would be better to not infinetly loop inside an actor.
But this is a problem with threadpools and not with the actor model itself.
If you need something that would block, you should move that into another thread, outside of the threadpool.
If you need to do (or check) something repeatedly then you can create an actor and use the pre_start
start method to schedule a message every X milliseconds to perform your operation.
e.g.:
#[derive(Debug, Clone)]
enum Message {
Loop,
Str(String),
}
// implement the Actor trait
impl Actor for MyActor {
type Msg = Message;
fn pre_start(&mut self, ctx: &Context<Message>) {
ctx.schedule(
Duration::from_secs(0), // initial delay
Duration::from_millis(1000), // time between messages
ctx.myself.clone(),
None,
Message::Loop, // your loop message
);
}
fn recv(&mut self, ctx: &Context<Message>, msg: Message, _sender: Sender) {
match msg {
Message::Loop => {
// do something repeatedly
println!(
"[{}]({:?}) LOOP",
ctx.myself().path(),
std::thread::current().id()
);
}
Message::Str(s) => {
// do something with the Str message
println!(
"[{}]({:?}) :: Received: \"{}\", self.value: {}",
ctx.myself().path(),
std::thread::current().id(),
s,
self.value
);
}
}
}
}
This way the actor can still respond to other messages, while repeatedly responding to the scheduled message.
Keeping this open for now because it’s a common occurrence and the explanation and solution provided by @hardliner66 is very good. We’ll get this included in the official docs and close this issue after.
For my understanding about actor model, i need 1 actor keep looping to do some task it should not hang the system, other actors should still working and do their job