2009-10-13 27 views
2

我有一個斯卡拉演員,每當客戶端請求時都會做一些工作。何時,並且只有當沒有客戶端處於活動狀態時,我希望Actor才能執行一些後臺處理。在Scala Actor中做空閒處理的最簡單方法是什麼?

這樣做最簡單的方法是什麼?我可以想到兩種方法:

  1. 產生一個超時的新線程並定期喚醒演員。一個簡單的方法,但我想避免創建另一個線程(以避免額外的代碼,複雜性和開銷)。

  2. Actor類有一個reactWithin方法,該方法可以用來從actor本身超時。但文檔說該方法不會返回。所以,我不知道如何使用它。

編輯;澄清:

假設後臺任務可以分解成可以獨立處理的更小的單位。

回答

6

好的,我看到我需要把我的2美分。從作者的回答中,我認爲「優先接收」技術正是這裏所需要的。可以在「Erlang: priority receive question here at SO」中找到討論。這個想法是首先接受高優先級的消息,並且只在沒有高優先級的消息時才接受其他消息。

由於Scala的演員都非常相似,二郎,一個簡單的代碼來實現,這將是這樣的:

def act = loop { 
    reactWithin(0) { 
    case msg: HighPriorityMessage => // process msg 
    case TIMEOUT => 
     react { 
     case msg: HighPriorityMessage => // process msg 
     case msg: LowPriorityMessage => // process msg 
     } 
    } 
} 

這個工作原理如下。演員有一個帶有消息的郵箱(隊列)。 receive(或​​)參數是一個部分函數,​​Actor庫在郵箱中查找可應用於此部分函數的郵件。在我們的情況下,它只會是HighPriorityMessage的一個對象。因此,如果Actor庫找到這樣的消息,它將應用我們的部分功能,並且我們正在處理高優先級的消息。否則,帶有超時0的reactWithin調用我們的部分函數,​​參數TIMEOUT,我們立即嘗試處理來自隊列的任何可能的消息(因爲它等待消息,我們不能排除可能得到HighPriorityMessage)。

+0

儘管我的解決方案在實踐中有效,但我認爲這更具慣用性,因此接受了它。我原本想使用reactWithin,但沒有在'TIMEOUT'上找到任何文檔 – HRJ 2009-10-17 04:19:08

2

聽起來像你描述的問題是不太適合演員子系統。一個Actor設計爲順序處理它的消息隊列:

  • 應該發生什麼,如果演員正在執行背景工作和新任務到達?

一位演員只能瞭解這是否因爲它執行後臺任務而不斷檢查其mailbox。你將如何實現這一點(即,如何將後臺任務編碼爲一個工作單元,以便演員可以中斷並檢查郵箱)?

  • 如果演員在主任務前的郵箱中有許多後臺任務,會發生什麼?

這些背景任務是否會被拋棄或被髮送給其他演員?如果是後者,你如何防止CPU給該演員執行任務的時間?

總而言之,聽起來更像是需要探索一些可以在後臺運行的網格式軟件(如Data Synapse)!

+0

我明白你的關心。但是當演員沒有做任何事時,我想要完成的後臺任務至關重要。回答你的問題:1.後臺任務可以分解爲更小的單元。如果演員在處理普通請求之前完成當前正在執行的後臺工作單元,那就沒問題。 2.希望在其他人在隊列中等待時使用Actor.mailboxSize忽略後臺任務。 – HRJ 2009-10-13 14:48:14

2

剛纔問這個問題,我試了一些完全怪異的代碼,它似乎工作正常。我不確定它是否存在問題。

import scala.actors._ 

object Idling 

object Processor extends Actor { 
    start 

    import Actor._ 

    def act() = { 
    loop { 

     // here lie dragons >>>>> 
     if (mailboxSize == 0) this ! Idling 
     // <<<<<< 

     react { 
     case msg:NormalMsg => { 
      // do the normal work 
      reply(answer) 
     } 

     case Idling=> { 
      // do the idle work in chunks 
     } 

     case msg => println("Rcvd unknown message:" + msg) 
     } 

    } 
    } 
} 

說明

loop參數內,但在調用react似乎當演員就要等待消息被調用之前的任何代碼。我在這裏發送一條Idling消息給自己。在處理此郵件時,我確保郵箱大小爲0,然後再進行處理。

+0

這可以工作的唯一方法是,如果您正在通過消息將閒置任務發送給此演員*不*。否則,任何空閒任務都將導致一個郵箱中有一個項目 – 2009-10-13 14:45:52

+0

@oxbow_lakes不知道我理解。此代碼在實踐中起作用,並且我通過消息發送空閒任務。 – HRJ 2009-10-13 14:51:29

+0

從你自己的回答中,我可以建議你正在發明一個「優先接收」(源自Erlang,但可以使用Scala參與者來實現) – 2009-10-13 16:39:24

相關問題