问题
I know that it is not recommended to block in the receive
method of an actor, but I believe it can be done (as long as it is not done in too many actors at once).
This post suggests blocking in preStart
as one way to solve a problem, so presumably blocking in preStart
is safe.
However, I tried to block in preRestart
(not preStart
) and everything seemed to just hang - no more messages were logged as received.
Also, in cases where it is not safe to block, what is a safe alternative?
回答1:
It's relatively safe to block in receive
when:
the number of blocked actors in total is much smaller than the number of total worker threads. By default there are ten worker threads, so 1-2 blocked actors are fine
blocking actor has its own, dedicated dispatcher (thread pool). Other actors are not affected
When it's not safe to block, good alternative is to... not block ;-). If you are working with legacy API that is inherently blocking you can either have a separate thread pool maintained inside some actor (feels wrong) or use approach 2. above - dedicate few threads to a subset of actors that need to block.
回答2:
Never ever block an actor.
If your actor is part of an actor hierarchy (and it should be), the actor system is not able to stop it. The actor's life-cycle (supervision, watchig etc.) is done by messaging. Stopping a parent actor of a blocking child will not work.
Maybe there are ways to couple the blocking condition with the actor's lifecycle. But this would lead to overload of complications and bad-style.
So, the best way is to do the blocking part outside of that actor. E.g. you could run the blocking code via an executor service in a separate thread.
来源:https://stackoverflow.com/questions/14505405/when-is-it-safe-to-block-in-an-akka-2-actor