As it's said in the comments, Combinatiors.loop
of the standard actors library is intended to save you from stack overflows, when the body of an actor is repeatedly executed.
But, does it make any sense to use loop
for an event-driven actors (react
), when message handling is, in fact, [almost] alway开发者_运维知识库s scheduled to be executed in a dedicated thread pool? Simple recursive call of the body seem to be a more efficient option.
Method Reactor.seq
(called by Combinatiors.loop
) is defined as follows:
private[actors] def seq[a, b](first: => a, next: => b): Unit = {
val killNext = this.kill
this.kill = () => {
this.kill = killNext
// to avoid stack overflow:
// instead of directly executing `next`,
// schedule as continuation
scheduleActor({ case _ => next }, null)
throw Actor.suspendException
}
first
throw new KillActorControl
}
Let's assume, next
is called directly. In this case, react
is executed immediately, message handling is scheduled, and the actor is suspended. No room for stack overflows...
Where am I wrong?
loop
is a general-purpose construct, that can be used both for thread-based and event-driven actors. If you try to handle messages of a thread-based actor recursively, you will end up quickly with stack overflow (unless your message handling is tail recursive, and can be optimized).
With regards to event-driven actors, you're absolutely right - recursive handling will be more effective, as long as stack overflow scenario specific for thread-based actors is not valid for event-driven ones (you even shouldn't make the recursion optimizable).
精彩评论