2014-11-03 6 views
4

Мы с Аккой познакомились.Akka Actor Props factory

От: Akka 2.3.6 (current) Actor Recommended Practice

Это пример актер называется DemoActor:

class DemoActor(magicNumber: Int) extends Actor { 
    def receive = { 
    case x: Int => sender() ! (x + magicNumber) 
    } 
} 

В Рекомендуемой практике раздел док говорится: «Это хорошая идея, чтобы обеспечить фабричные методы на сопутствующий объект каждого Актера, который помогает сохранить возможность создания подходящих реквизитов как можно ближе к определению актера ». Что они делают так:

object DemoActor { 
    def props(magicNumber: Int): Props = Props(new DemoActor(magicNumber)) 
} 

Вопрос: В чем разница между указанием завода по методу реквизита, как:

object DemoActor { 
    def props(magicNumber: Int): Props = Props(classOf[DemoActor], magicNumber) 
} 

В случае, если Вы пропустили это, разница была аргумент конструктору реквизита:

new DemoActor(magicNumber) 

В.С.

classOf[DemoActor], magicNumber 

Из той же АККИ страницы документации немного дальше вверх в Props section, он также упоминает при использовании Props(classOf[ActorWithArgs], "arg1"): «Присутствие согласующего конструктора проверяется в процессе строительства объекта реквизита, в результате чего в IllegalArgumentEception, если не найдено ни одного или нескольких конструкторов соответствия. "

Это хорошо, не так ли?!? ....

ответ

10

Это хорошо, не так ли?!? ....

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

Интересная вещь о методе Propsapply в том, что когда вы пишете:

Props(new DemoActor(magicNumber)) 

конструктор актера не вызывается сразу после создания экземпляра Реквизит. Вызов конструктора передается по имени, а не по значению. Вы можете увидеть это в подписи метода Propsapply:

def apply[T <: Actor](creator: ⇒ T)(implicit arg0: ClassTag[T]): Props 

Обратите внимание на стрелку вправо в параметре создателя. Это позволяет отложить конструкцию создателя и, возможно, выполнить другой процесс для удаленных участников.

Потенциальная опасность здесь заключается в том, что операция new закрывается по объему и фиксирует значение, которое не предназначено для сериализации или не является сериализуемым, что делает объект реквизита также не сериализуемым. Вот почему документация рекомендует делать это в сопутствующем объекте актера - чтобы свести к минимуму риск закрытия данных, которые не предназначены для сериализации.

+0

Спасибо за кучи за отличный ответ. Вы дали мне момент о-о-вид и немного больше уверенности в акке. Спасибо, что указали, что подпись подписи на реквизитах будет работать как звонок по имени. Первоначально я думал, что «classOf [DemoActor]» был исключен из-за производительности (учитывая, что из моего прошлого опыта в поиске Java-классов было дорого). Ошибка сборки времени компиляции в моем случае хорошая, я буду оставлять * динамические * поисковые запросы для особых случаев, когда мне это действительно нужно. Спасибо еще раз за помощь. – neurozen

+1

Параметр call-by-name является 'scala.Function0' во время выполнения. Как Akka сериализует объект функции? –

+0

Я не совсем уверен, но я считаю, что байт-коды фактически передаются, а затем загружаются с удаленной стороны. Он работает только в том случае, если нет контекста, захваченного закрытием, которое не сериализуется. Если вы действительно хотите знать, как это делается, я бы предложил задать его как свой собственный вопрос. –

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