2013-09-05 7 views
9

Ich versuche den besten Ansatz zu finden, den gleichen Verbindungspool zwischen den Akteuren zu teilen, die mit den Cluster-Mitarbeitern arbeiten. Ich habe die folgende Struktur:Akka und ReactiveMongo

Meister Schauspieler -> Worker Schauspieler (kann bis zu 100 oder mehr sein) -> MongoDB

zwischen Arbeitern und MongoDB ich reactivemongo setzen wollen, aber ich bin nicht sicher, wie genau Bereitstellen von Verbindungspool-Sharing zwischen allen Akteuren.

Nach reactivemongo Dokumentation:

A MongoDriver Beispiel ein Schauspieler System verwaltet; Eine Verbindung verwaltet einen Pool von Verbindungen. Im Allgemeinen werden MongoDriver oder MongoConnection nicht mehr als einmal instanziiert. Sie können eine Liste mit einem oder mehreren Servern bereitstellen. Der Treiber wird erraten, ob es sich um einen eigenständigen Server oder eine Replikat-Konfiguration handelt. Selbst mit einem Replikknoten sucht der Treiber nach anderen Knoten und fügt sie automatisch hinzu.

Sollte ich es einfach im Hauptakteur erstellen und dann mit jeder Nachricht bündeln? So würde dies in der Meister-Schauspieler sein:

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

Und dann in einer Nachricht gebe ich den Anschluss an Akteuren. Oder sollte ich eine Verbindung in jedem Work Actor abfragen und nur den Treiber in einer Nachricht übergeben?

Jede Hilfe wird sehr geschätzt. Danke.

Antwort

14

Ich würde die driver und connection im Hauptakteur erstellen. Ich würde dann die Arbeiterakteure so einrichten, dass sie eine Instanz von MongoConnection als Konstruktorargument verwenden, sodass jeder Worker einen Verweis auf die Verbindung hat (die eigentlich ein Proxy für einen Pool von Verbindungen ist). Dann, in etwas wie preStart, muss der Hauptdarsteller die Worker erstellen (von denen ich annehme, dass sie geroutet sind) und die Verbindung als arg bereitstellen. Ein sehr vereinfachtes Beispiel könnte wie folgt aussehen:

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 = { 
    ... 
    } 
} 

Dieser Code ist nicht richtig, aber zumindest zeigt die hohe Konzepte, die ich beschrieben.

+0

Danke für Ihre Antwort, das sieht gut aus, ich werde es versuchen. –

6

Die Antwort von cmbaxter funktioniert, solange Sie die Arbeiterdarsteller nicht remote instanziieren müssen. MongoConnection ist nicht serialisierbar.

Ich fand diesen Artikel https://github.com/eigengo/akka-patterns/wiki/Configuration sehr hilfreich. Die Grundidee besteht darin, ein Merkmal namens Configured zu implementieren, das von der Hauptanwendung ausgefüllt wird. Die Akteure können dann dieses Merkmal verwenden, um Zugriff auf lokale, nicht serialisierbare Objekte wie MongoConnection zu erhalten.