2016-03-04 24 views
0

對於一次實習求職面試,我的朋友要求我在規定的時間段內與Scala演員實施合併排序。爲什麼這個Scala actor代碼需要阻塞才能工作?

的代碼最終看上去像這樣:

https://dl.dropboxusercontent.com/u/214507961/MergeActor.scala

基本上,應用程序將啓動,象這樣:

import akka.pattern.ask 
import akka.util.Timeout 
import scala.concurrent.duration._ 
import akka.actor.ActorSystem 
import akka.actor.{ActorRef, Props} 

def main(args: Array[String]): Unit = { 

    val system = ActorSystem("CrappyActor1") 

    implicit val timeout = Timeout(2.second) 
    implicit val ec = system.dispatcher 

    val firstActor: ActorRef = system.actorOf(Props[SortActor]) 
    val result = firstActor ? UnsortedList(List(1,3,2,4,-1)) 
    result.onSuccess { 
     case SortedList(element) => Print.line("" + element.toString) 
     case _ => Print.asrt(false, "Only a Sorted list was supposed to arrive.") 
    } 
    result.onFailure { 
     case _ => Print.asrt(false, "Failure.") 
    } 
    system.shutdown() 
} 

^第一男主角會被創建並傳遞的無序列表數字。它會收到這個清單,如果清單長度超過兩個,它將分成一半,每半個清單給一個新的兒童演員。

如果列表只包含1或2個元素,則列表將被排序併發送回發件人/父行動者,直到返回完全排序的列表。

的事情是,在「MergeActor.scala」上線62,我需要添加:

Thread.sleep(5000) // This keeps the sender in existence. 

^或者合併排序沒有完成。爲什麼這個睡眠是必要的?你會怎麼做?

*更新*

添加 「了Thread.sleep(10000)」 在 「主」 年底前 「system.shutdown()」 沒有工作。在「MergeActor.scala」中註釋掉「Thread.sleep(5000)」導致「main」以「result.onFailure」結束。

"Failure: akka.pattern.AskTimeoutException: Ask timed out on [Actor[akka://CrappyActor1/user/$a#-1508387879]] after [2000 ms]" in thread CrappyActor1-akka.actor.default-dispatcher-3: 

沒有「Thread.sleep(5000)」,結果不會在兩秒鐘超時之前回來。

另外,我剛發生故障之前得到這個錯誤:

[INFO] [03/04/2016 15:34:05.696] [CrappyActor1-akka.actor.default-dispatcher-3] [akka://CrappyActor1/deadLetters] Message [mergeactors.MergeActor$SortedList] from Actor[akka://CrappyActor1/user/$a/$b#1429046332] to Actor[akka://CrappyActor1/deadLetters] was not delivered. [1] dead letters encountered. This logging can be turned off or adjusted with configuration settings 'akka.log-dead-letters' and 'akka.log-dead-letters-during-shutdown'. 
+0

我認爲合併是從屬線程執行。你必須讓主線程保持活動狀態,否則通常會結束工作,其他線程會在以後關閉。 – Rumoku

+0

@rumoku我對阿卡一無所知。我所知道的是,如果我註釋掉「Thread.sleep(5000)」,我會在主線程中獲得「akka.pattern.AskTimeoutException」,這是創建父actor的線程。另外,我不認爲我正在進行任何合併 - 執行合併的線程在返回排序列表後自行排序「PoisonPill」本身。保持主線程不活動。 –

回答

1

一個可能的原因可能是在程序退出的結果返回之前。

您必須記住,即使在antoher線程或actor中完成了一些工作,所有執行都會解耦,並且Main退出程序。

對於初學者,我建議只使用一個concurrency model,不要混合ActorsFutures。當使用ask?模式時會發生這種情況。

這樣你現在也必須記住可能的超時時間。

更新:答案

您所描述的問題沒有連接到actors但斯卡拉Futures擴展問題。在這裏您可以獲得基本的文檔和使用示例:http://docs.scala-lang.org/overviews/core/futures.html

嘗試

Await.result(result, Duration.Inf) 
+0

在「system.shutdown()」之前的「main」末尾添加「Thread.sleep(10000)」不起作用。在「MergeActor.scala」中註釋掉「Thread.sleep(5000)」導致「main」以「result.onFailure」結束。沒有「Thread.sleep(5000)」,結果在兩秒鐘超時之前不會回來。 –

+0

原因是「akka.pattern.AskTimeoutException」 –

相關問題