2017-02-15 5 views
2

Всякий раз, когда я создаю актера, который нуждается в некоторых асинхронно полученных данных, чтобы инициализировать себя, я нахожу себя таким идиомом. У него есть имя? (И это лучший способ сделать это?)Есть ли имя для этой асинхронной идиомы инициализации актера?

class AsyncInitActor(db: Database, someId: UUID) extends Actor with ActorStash { 
    case class Initialize(something: Something) 

    override def preStart() = { 
     db.getSomething(someId) onSuccess { something => 
      self ! Initialize(something) 
     } 
    } 

    def receive = { 
     case Initialize(something) => 
      context become initialized(something) 
      unstashAll() 

     case _ => stash() 
    } 

    def initialized(something): Receive = { 
     case whatever => 
    } 
} 

В случае субъектов, созданных кластеров сегментирование, асинхронный запрос происходит в receive вместо preStart.

Чтобы быть ясным, я не ищу шаблон GoF.

ответ

0

Ближайший дизайн, который приходит мне на ум, является прокси.

За документацией here:

Design заменяющего, или прокси-сервера, объект, который: конкретизирует реальный объект в первый раз, когда клиент делает запрос прокси-сервера, запоминает идентификатор этого реального объекта, и направляет запрос на подстрекательство к этому реальному объекту. Затем все последующие запросы просто перенаправляются непосредственно в инкапсулированный реальный объект.

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

+1

Нет, это не прокси. Актер не перенаправляет запросы другому актеру, он просто задерживает те, которые он обрабатывает, до тех пор, пока не инициализируется. – Derecho

+0

Вы * можете * спроектировать его таким образом, чтобы обертка ожидала инициализации и соответственно переместилась –

0

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

Я бы сказал, вы в основном описал Заводская модель. И если ваши актеры - это концепции DDD, то это будет в контексте Репозитория DDD. Другими словами, вы имеете дело со сложным созданием объекта вместе с его валидацией - часть. Одна из обязанностей репозитория DDD заключается в том, чтобы получить действительный совокупный корень.

Мои два цента.

Sergiy

<> <

+0

Нет, это не шаблон Factory. Я ищу имя для этого специально асинхронного шаблона. Может быть, лучше назвать идиомой. – Derecho

+0

Я не совсем понимаю ваши намерения здесь. Асинхронность операции не изменяет намерения. Намерение определяет шаблон. Шаблоны по определению решают проблему повторения. Тот факт, что вы меняете его на идиому, не устраняет его сути. Это в вашем случае многоступенчатое создание действительного актера. –

+0

Мое намерение - выяснить, имеет ли эта конкретная идиома * асинхронная инициализация актера имя. Вызов фабрики не означает, что это то, что происходит. – Derecho

1

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

http://doc.akka.io/docs/akka/current/scala/fsm.html

Я полагаю, вы могли бы объединить оба подхода.

+0

Можете ли вы привести пример? Что вы делаете с сообщениями, которые поступают в исходное состояние, если вы их не забиваете? – Derecho

+0

Я думаю, что для этой цели существует проблема. http://stackoverflow.com/questions/28005231/correct-way-to-postpone-messages-in-akka Конечно, вы также можете сохранить в статусе актера. Честно говоря, я обычно использовал FSM для отклонения других сообщений до того, как поведение изменилось с «стать» до некоторого состояния READY. Мне не нужно было принимать сообщения до того, как актер будет готов. https://github.com/SalmaKhater/Learning-Akka/blob/master/hotswap-behavior/src/main/scala/FSM.scala - еще один пример. – dres