How do I wait for an actor to stop during Play Framework shutdown?

天涯浪子 提交于 2020-01-01 06:18:12

问题


The below code throws a java.lang.IllegalMonitorStateException exception when I shutdown the play server; it is caused by the a.wait(1000) call in the onStop method. Could anyone tell me why this is the case and how to gracefully wait for an actor to complete within Play framework 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 }

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()
    }
}

Update:

Here is the complete solution, taking the below answer:

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()
    }
}

回答1:


"Graceful Stop gracefulStop is useful if you need to wait for termination or compose ordered termination of several actors:

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
}

"

  • http://doc.akka.io/docs/akka/2.0/scala/actors.html#Graceful_Stop

PS. Googling for "graceful actor akka" gives the answer as the top result.



来源:https://stackoverflow.com/questions/19412869/how-do-i-wait-for-an-actor-to-stop-during-play-framework-shutdown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!