2013-12-11 5 views
1

У меня есть аккорская система, использующая scala. Теперь мне нужно настроить несколько устройств параллельно, поэтому у меня есть оператор Manager, который управляет всеми этими задачами конфигурации. Чтобы на самом деле сконфигурировать их, он будет создавать актера Worker для каждой конфигурации, чтобы они запускались параллельно или параллельно. Теперь актеру Worker действительно не нужно получать сообщения от менеджера во время конфигурации, которые ему только нужно сделать, а затем сообщить, что он вернулся к Manager.Актер хорошая практика?

Теперь вопрос я передать инструкции и ActorRef в Manager в конструкторе Worker или я его создать, а затем отправить ему сообщение, как Do(action: => Unit) и будет отвечать на sender после завершения? Есть ли соглашение, как это сделать или считается хорошей практикой?

EDIT: Как Владимир Матвеев напомнил мне ссылку на Manager не является проблемой, как это уже известно по иерархии в context.parent. Это оставляет только вопрос о том, как передать работу Worker.

+1

Если диспетчер '' управляет рабочими напрямую, вам не нужно передавать им ссылку 'Manager'. Работники могут использовать 'context.parent' для доступа к' Manager'' ActorRef'. –

+0

@ Владымир Матвеев. О да, это правда. Но что делать с работой? Также 'context.parent' все еще' Manager', если я появляюсь в будущем с помощью 'context.scheduler.schedule ...'? Я думаю, это должно быть потому, что это закрытие, но я не уверен в этом. – mgttlinger

+1

Если вы используете «контекст» внутри актера для создания дочерних актеров, у них будет этот актер в качестве родителя, независимо от того, где вы используете «контекст» внутри этого актера. Это довольно логично, потому что, как вы сказали, переменная 'context' просто закрыта, но она по-прежнему остается одним и тем же« контекстом ». –

ответ

2

Вы правы, работа должна быть передана работнику через сообщения. Поскольку это самый безопасный способ общения с актером. Он также позволяет вам использовать диспетчера перед актером для разделения назначенной работы над несколькими работниками.

Чтобы сделать вещи ясно, вот короткий пример:

import akka.actor.Actor 
import akka.actor.Props 

case class Start() 
case class Finished() 
case class Do(action:() => Unit) 

class Manager extends Actor { 

    override def preStart() = 
    self ! Start() 

    def receive = { 
    case Start() => 
     val workers = context.actorOf(
     Props[Worker].withRouter(RoundRobinRouter(nrOfInstances = 5))) 
     context.system.scheduler.schedule(5 seconds, 5 seconds, workers, Do(() => 1 * 1)) 

    case Finished() => 
     println("A worker finished work.") 
    } 
} 

class Worker extends Actor { 
    def receive = { 
    case Do(f) => 
     f() 
     sender ! Finished() 
    } 
} 

После того, как менеджер запускается, это создаст 5 рабочих и послать им что-то, чтобы работать на каждые 5 секунд. Рабочие будут выполнять работу и сообщать, когда они будут завершены. Вы можете использовать sender (всегда сообщать эмитенту о работе) или context.parent (всегда отчитываться перед менеджером), чтобы сообщить о завершенной работе.

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