2011-05-06 2 views
4

Как указано в комментариях, Combinatiors.loop стандартной библиотеки актеров предназначен для спасения вас от переполнения стека, когда тело актера неоднократно выполняется.Возможно ли получить ошибку StackOverflow с рекурсивными участниками, управляемыми событиями?

Но имеет ли смысл использовать loop для актеров, управляемых событиями (react), когда обработка сообщений фактически фактически запланирована для выполнения в выделенном пуле потоков? Простой рекурсивный вызов тела представляется более эффективным вариантом.


Метод Reactor.seq (названный Combinatiors.loop) определяется следующим образом:

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 

}

Давайте предположим, next вызывается непосредственно. В этом случае react выполняется немедленно, message handling is scheduled, и актер приостановлен. Нет места для переполнения стека ...

Где я ошибаюсь?

ответ

0

loop - универсальная конструкция, которая может использоваться как для потоковых, так и для событийных актеров. Если вы попытаетесь обработать сообщения рекурсивного потока на основе потоков, вы быстро закончите с переполнением стека (если ваша обработка сообщений не рекурсивна и может быть оптимизирована).

Что касается актеров, управляемых событиями, вы абсолютно правы - рекурсивная обработка будет более эффективной, если сценарий переполнения стека, характерный для субъектов, основанных на потоках, недействителен для событийных событий (вы даже должны " t сделать рекурсию оптимизируемой).

Смежные вопросы