2017-02-14 57 views
0

我接近Lagom + CQRS /事件採購是第一次,我想實現像一個行爲:如何在Lagom實施「過期後」副作用?

  1. 服務電話是(通過REST API調用例如)執行
  2. 一命令被運行並觸發一個改變狀態的事件(例如啓動某種計時器)。
  3. 經過預先定義的時間間隔後,計時器應該過期,因此應該觸發新事件(無其他外部命令)來改變狀態以使計時器無效。

前兩個步驟很簡單,但是一旦我觸發了TimerStartedEvent並改變了狀態,我該如何在一段固定的時間後「安排」一個事件?我如何實施第三步?

+0

我對Lagom並不熟悉,但既然您在您的代碼中列出了Akka,我會建議Akka調度程序爲您的演員安排超時消息,如果這適用於您的情況。 我在過去一年編寫的Job Orchestration應用程序中使用了它,這在行爲上類似:調用REST API,一旦REST API完成完成操作應該觸發,但與REST調用同時使用Akka Scheduler安排超時消息。無論誰先進入目標Actor定義如何終止這個呼叫 – MattEdge

+0

@MattEdge這是一個好主意! Lagom建立在Akka之上,所以我將它列在我的標籤中。唯一的「缺點」是這個外部服務應該調用一些API來傳遞超時,所以在CQRS中它應該執行一個命令來觸發一個改變狀態的事件。是否應該在沒有外部特定命令的情況下生成「正確」方式或事件? –

+0

將結果通過REST API路由到關聯的Actor後,我們在內部生成了該事件,然後再重新生成該命令。但是如果超時發生首先演員終止,並且API不能查詢適當的演員(我們已將其記錄下來用於跟蹤目的)。 – MattEdge

回答

0

我發現了一個可能的實現(實際上在online-auction-scala sample code本身)。

因爲Lagom它構建在Akka之上,它會注入ActorSystem,因此您可以使用system.scheduler.schedule調用來安排將來的某些事情。

要回答這個問題的CQRS一部分,示例代碼是這樣的:

system.scheduler.scheduler(offset, delay) { 
    checkFinishBidding() 
} 

checkFinishBidding() = { 
    registry.refFor[Entity](id).ask(SomeCommand) 
} 

所以當時間觸發時,可以從註冊表中出隊的實體裁判和運行一個命令就像一個正常的服務電話。

+0

這是一個很好的解決方案,但有一點需要注意:在線拍賣應用程序中的示例代碼尚未集羣感知。這意味着如果您在多個節點上運行服務(建議用於恢復),則計劃任務將在所有節點上運行。爲了避免這種情況,您可以使用Akka [Cluster Singleton](http://doc.akka.io/docs/akka/2.4/scala/cluster-singleton.html)。 –

+0

另外,我認爲你可以接受你自己的答案,如果你滿意的話:) –