2012-12-19 35 views
22

我正在使用Play!編寫一個用Scala編寫的Web應用程序!框架和Akka。代碼基本上是這樣組織的:播放控制器向Akka演員發送消息。演員反過來與一個持久層交談,該層抽象數據庫訪問。在應用這些部件的使用的一個典型的例子:在CRUD Web應用程序中使用Akka actors

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] = ??? 
} 

正如你所看到的,這是基本的CRUD模式,就像你會在其他語言和框架看。查詢會傳遞到下面的圖層,並且當應用程序從數據庫中獲取結果時,該結果會返回到用戶界面。唯一相關的區別是使用actor和異步調用。

現在,我對演員的概念很陌生,所以我還沒有完全理解它。但是,從我讀過的,這不是演員應該如何使用。但是,請注意,在某些情況下(例如,在插入訂單時發送電子郵件),我們確實需要真正的異步消息傳遞。

所以,我的問題是:以這種方式使用演員是一個好主意嗎?利用Futures和Akka的其他併發功能,在Scala中編寫CRUD應用程序有哪些選擇?

+1

看看鍵入的頻道 - 他們出來後,你張貼這個。他們有一些有趣的消息流特性,所以你可以做一些事情,比如通過幾個角色傳遞消息:OrderRepository.insert(order) - ! - > sender - ? - > sendEmail - ? - > displayResult。 –

回答

5

儘管基於角色的併發與開箱即用的事務操作不相符,但如果與持久層良好地配合,則不會阻止您使用actor。如果你可以保證插入(寫)是原子,那麼你可以安全地讓一羣演員爲你做。通常數據庫有一個線程安全讀取所以找到也應該按預期工作。除此之外,如果插入不是線程安全的,則可以將一個WriteActor專門用於寫入操作,並且順序處理消息將確保您的原子性。

2

有一點需要注意的是,一個角色一次處理一條消息,在這種情況下這將是相當有限的。您可以使用routers來使用一組演員。

您的示例根據數據庫驅動程序定義存儲庫的阻止API,這可能是唯一可以執行的操作。如果可能的話,你也應該在那裏尋找一個異步API,例如返回期貨。在演員中,您將接着發送未來的結果pipe

+0

是的,控制器依賴於一個'ActorRef',它可以是一個簡單的角色以及一個路由器。 –