Actix actor receiving from blocking source

HI!

I'm new to actix and also to actor systems. There is a library that supports pub/sub and does not support async/await. So I need an actor that subscribes to messages from this library and blocks on waiting for messages. I know that there is a SyncArbiter but I'm struggling to understand where do I place my infinite loop

loop {
  let msg = outside_world.wait();
  another_actor.send(msg).await;
}

Or more generally: how such problems are solved in actor model?

1 Like

Could you just spawn a thread and put the loop in the thread? You’d have to send to another actor with do_send or try_send it looks like.

I’m not very familiar with actix so there may be a more idiomatic way to accomplish this, but this should work.

Yeah I can but isn't it digression from actor model?

I'm starting to think that if you isolate actor part of your program then it can't execute anything unless you constantly feed it with external events from such threads. It only reacts to messages but cannot actively communicate to external world. This is because you have to process message synchronously i.e. cannot block (or await) inside actix::Actor::handle().

Yes, in theory it does not fit with the idealized actor model but the actors are still managing threads and synchronous events under the hood. You just don’t see it because it’s all handled for you. In this case though if the incoming events are coming from synchronous code then the simplest thing to do is to set up a thread to listen for those events and then feed it into your actors.

Without having a thread listen for the events at all times, you’d probably need to structure the code where instead of waiting for an event, the function just checks to see if there is an event available. And if not, you could schedule an actor to poll again in some amount of time. If there’s just a single event source, this is unlikely to be any more efficient. Though if it makes it easier to reason about your code, it might be worth it to you.