2013-09-05 2 views
9

Я пытаюсь найти наилучший подход к тому, чтобы использовать один и тот же пул связи между действующими лицами, работающими с кластерными рабочими. У меня есть следующая структура:Akka and ReactiveMongo

Мастер Актер -> Worker Актеры (может быть до 100 или более) -> MongoDB

Между рабочими и MongoDB я хочу поставить reactivemongo, однако я не уверен, как именно обеспечить совместное использование пула соединений между всеми участниками.

Согласно reactivemongo документации:

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

Должен ли я просто создавать его в мастер-актере, а затем связывать с каждым сообщением? Таким образом, это было бы в мастер-актера:

val driver = new MongoDriver 
val connection = driver.connection(List("localhost")) 

А потом я прохожу связь с актерами в сообщении. Или я должен запросить соединение в каждом Рабочем Актере и передать только драйвер в сообщении?

Любая помощь очень ценится. Спасибо.

ответ

14

Я бы создал driver и connection в главном актере. Затем я создавал бы рабочих участников, чтобы взять экземпляр MongoConnection в качестве аргумента конструктора, чтобы каждый рабочий имел ссылку на соединение (которое действительно является прокси для пула соединений). Затем, в чем-то вроде preStart, попросите мастера создать рабочих (которые я предполагаю, маршрутизируются) и поставьте соединение как arg. Очень упрощенный пример может выглядеть следующим образом:

class MongoMaster extends Actor{ 
    val driver = new MongoDriver 
    val connection = driver.connection(List("localhost")) 

    override def preStart = { 
    context.actorOf(Props(classOf[MongoWorker], connection).withRouter(FromConfig())) 
    } 

    def receive = { 
    //do whatever you need here 
    ... 
    } 
} 

class MongoWorker(conn:MongoConnection) extends Actor{ 
    def receive = { 
    ... 
    } 
} 

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

+0

Спасибо за ваш ответ, это выглядит хорошо, я дам ему попробовать. –

6

Ответ cmbaxter работает до тех пор, пока вам не нужно создавать экземпляр рабочих участников удаленно. MongoConnection не является сериализуемым.

Я нашел эту статью https://github.com/eigengo/akka-patterns/wiki/Configuration очень полезной. Основная идея заключается в реализации признака Configured, который заполняется основным приложением. Затем актеры могут использовать эту черту для доступа к локальным, несериализуемым объектам, таким как MongoConnection.