2013-10-16 24 views
3

下面的代码抛出一个java.lang.IllegalMonitorStateException异常当我关闭播放服务器;它是由a.wait(1000)调用onStop方法引起的。谁能告诉我为什么会出现这种情况,以及如何优雅地等待演员在Play框架关闭中完成?如何等待演员在Play Framework关机期间停止播放?

import play.api.GlobalSettings 
import play.api.libs.concurrent.Akka 
import akka.actor.{ Actor, Props } 
import play.api.libs.concurrent.Execution.Implicits.defaultContext 
import play.api.Play.current 
import models.{ TestActor, StartMessage, StopMessage } 

object Global extends GlobalSettings { 

    override def onStart(application : play.api.Application) { 
     val a = Akka.system.actorOf(Props[TestActor], name = "test-actor") 
     a ! StartMessage("Start instruction") 

    } 

    override def onStop(application : play.api.Application) { 
     val a = Akka.system.actorSelection("akka://application/user/test-actor") 
     a ! StopMessage("Stop instruction") 
     a.wait(1000) 
     Akka.system.shutdown() 
    } 
} 

更新:

下面是完整的解决方案,采取了以下答案:

import play.api.GlobalSettings 
import play.api.libs.concurrent.Akka 
import akka.actor.{ Actor, Props } 
import play.api.libs.concurrent.Execution.Implicits.defaultContext 
import play.api.Play.current 
import models.{ TestActor, StartMessage, StopMessage } 
import akka.pattern.gracefulStop 
import scala.concurrent.Future 
import scala.concurrent.duration.FiniteDuration 
import scala.concurrent.Await 
import com.typesafe.config.impl.ResolveContext 
import com.typesafe.config.impl.ResolveContext 
import akka.actor.ActorIdentity 

object Global extends GlobalSettings { 

    override def onStart(application : play.api.Application) { 
     val a = Akka.system.actorOf(Props[TestActor], name = "test-actor") 
     a ! StartMessage("Start Instruction") 
    } 

    override def onStop(application : play.api.Application) { 
     val a = Akka.system.actorFor("akka://application/user/test-actor") 
     a ! StopMessage("Stop Instruction") 

     try { 
      val stopped : Future[Boolean] = gracefulStop(a, scala.concurrent.duration.Duration(5, "seconds")) 
      Await.result(stopped, scala.concurrent.duration.Duration(6, "seconds")) 
      // the actor has been stopped 
     } 
     catch { 
      case e : akka.pattern.AskTimeoutException => // the actor wasn't stopped within 5 seconds 
     } 

     Akka.system.shutdown() 
     Akka.system.awaitTermination() 
    } 
} 
+0

你可能会觉得这篇文章很有用:http://letitcrash.com/post/30165507578/shutdown-patterns-in-akka-2 –

回答

6

“如果你需要等待终止或撰写有序正常停止 gracefulStop是有用终止几名演员:

import akka.pattern.gracefulStop 
import akka.dispatch.Await 
import akka.actor.ActorTimeoutException 

try { 
    val stopped: Future[Boolean] = gracefulStop(actorRef, 5 seconds)(system) 
    Await.result(stopped, 6 seconds) 
    // the actor has been stopped 
} catch { 
    case e: ActorTimeoutException ⇒ // the actor wasn't stopped within 5 seconds 
} 

PS。谷歌搜索“优雅的演员阿卡”给出了答案作为最重要的结果。