2012-12-19 4 views
22

Ich arbeite an einer Web-Anwendung, die in Scala geschrieben wurde. Rahmen und Akka. Der Code ist im Prinzip wie folgt organisiert: Play Controller senden Nachrichten an Akka-Akteure. Die Akteure sprechen wiederum mit einer Persistenzschicht, die den Datenbankzugriff abstrahiert. Ein typisches Beispiel für die Verwendung dieser Komponenten in der Anwendung:Verwenden von Akka-Darstellern in einer CRUD-Webanwendung

class OrderController(orderActor: ActorRef) extends Controller { 
    def showOrders(customerId: Long) = { 
    implicit request => Async { 
     val futureOrders = orderActor ? FindOrdersByCustomerId(id) 

     // Handle the result, showing the orders list to the user or showing an error message. 
    } 
    } 
} 

object OrderActor extends Actor { 
    def receive = { 
    case FindOrdersByCustomerId(id) => 
     sender ! OrderRepository.findByCustomerId(id) 
    case InsertOrder(order) => 
     sender ! OrderRepository.insert(order) 
     //Trigger some notification, like sending an email. Maybe calling another actor. 
    } 
} 

object OrderRepository { 
    def findByCustomerId(id: Long): Try[List[Order]] = ??? 
    def insert(order: Order): Try[Long] = ??? 
} 

Wie Sie sehen können, ist dies die grundlegenden CRUD-Muster, viel wie das, was man in anderen Sprachen und Frameworks sehen würde. Eine Abfrage wird an die darunter liegenden Ebenen übergeben, und wenn die Anwendung ein Ergebnis von der Datenbank erhält, wird dieses Ergebnis wieder erreicht, bis es die Benutzeroberfläche erreicht. Der einzige relevante Unterschied ist die Verwendung von Aktoren und asynchronen Aufrufen.

Nun, ich bin sehr neu in dem Konzept der Schauspieler, so dass ich es noch nicht ganz verstehe. Aber nach dem, was ich gelesen habe, sollten Schauspieler nicht so benutzt werden. Beachten Sie jedoch, dass in einigen Fällen (z. B. beim Senden einer E-Mail beim Einfügen einer Bestellung) eine echte asynchrone Nachrichtenübermittlung erforderlich ist.

Also, meine Frage ist: Ist es eine gute Idee, Schauspieler auf diese Weise zu verwenden? Was sind die Alternativen für das Schreiben von CRUD-Anwendungen in Scala, die Nutzung von Futures und die anderen Parallelitätsfähigkeiten von Akka?

+1

Werfen Sie einen Blick auf typisierte Kanäle - sie kamen heraus, nachdem Sie dies gepostet haben. Sie haben einige interessante Funktionen für den Nachrichtenfluss, so dass Sie beispielsweise Nachrichten an mehrere Akteure weitergeben können: OrderRepository.insert (order) -! -> sender -? -> sendEmail -? -> displayResult. –

Antwort

5

Die actorbasierte Parallelität passt zwar nicht zu den transaktionalen Vorgängen, aber das hindert Sie nicht daran, Akteure auf diese Weise zu verwenden, wenn Sie gut mit der Persistenzschicht spielen. Wenn Sie garantieren können, dass der Einsatz (schreiben) atomar ist, dann können Sie sicher einen Pool von Schauspielern haben, der es für Sie tut. Normalerweise haben Datenbanken einen thread-sicheren Lesevorgang, so dass finden sollte auch wie erwartet funktionieren. Abgesehen davon, wenn die Einfügung nicht threadsicher ist, können Sie einen einzigen WriteActor haben, der einfach für Schreiboperationen dediziert ist und die sequentielle Verarbeitung von Nachrichten wird Atomizität für Sie sicherstellen.

2

Eine Sache zu beachten ist, dass ein Akteur eine Nachricht zu einer Zeit verarbeitet, die in diesem Fall ziemlich einschränkend wäre. Sie können einen Pool von Akteuren verwenden, indem Sie routers verwenden.

Ihr Beispiel definiert eine blockierende API des Repositorys, was je nach Datenbanktreiber möglicherweise die einzige Möglichkeit ist. Wenn möglich, sollten Sie dort auch eine asynchrone API verwenden, d. H. Wiederkehrende Futures. Im Akteur würdest du dann stattdessen das Ergebnis der Zukunft an den Absender pipe senden.

+0

Ja, der Controller hängt von einem 'ActorRef' ab, der sowohl ein einfacher Akteur als auch ein Router sein könnte. –