diff --git a/akka-actor/src/main/scala/akka/pattern/Patterns.scala b/akka-actor/src/main/scala/akka/pattern/Patterns.scala index 6840716bad..abf435edc5 100644 --- a/akka-actor/src/main/scala/akka/pattern/Patterns.scala +++ b/akka-actor/src/main/scala/akka/pattern/Patterns.scala @@ -15,16 +15,16 @@ import akka.util.Duration object Patterns { /** - * Returns a [[akka.dispatch.Future]] that will be completed with `Right` `true` when + * Returns a [[akka.dispatch.Future]] that will be completed with success (value `true`) when * existing messages of the target actor has been processed and the actor has been * terminated. * * Useful when you need to wait for termination or compose ordered termination of several actors. * * If the target actor isn't terminated within the timeout the [[akka.dispatch.Future]] - * is completed with `Left` [[akka.actor.ActorTimeoutException]]. + * is completed with failure [[akka.actor.ActorTimeoutException]]. */ - def gracefulStop(target: ActorRef, timeout: Duration, system: ActorSystem): Future[Boolean] = { - akka.pattern.gracefulStop(target, timeout)(system) + def gracefulStop(target: ActorRef, timeout: Duration, system: ActorSystem): Future[java.lang.Boolean] = { + akka.pattern.gracefulStop(target, timeout)(system).asInstanceOf[Future[java.lang.Boolean]] } } \ No newline at end of file diff --git a/akka-actor/src/main/scala/akka/pattern/package.scala b/akka-actor/src/main/scala/akka/pattern/package.scala index 91159d08a9..b09ee56897 100644 --- a/akka-actor/src/main/scala/akka/pattern/package.scala +++ b/akka-actor/src/main/scala/akka/pattern/package.scala @@ -21,14 +21,14 @@ import akka.util.Duration package object pattern { /** - * Returns a [[akka.dispatch.Future]] that will be completed with `Right` `true` when + * Returns a [[akka.dispatch.Future]] that will be completed with success (value `true`) when * existing messages of the target actor has been processed and the actor has been * terminated. * * Useful when you need to wait for termination or compose ordered termination of several actors. * * If the target actor isn't terminated within the timeout the [[akka.dispatch.Future]] - * is completed with `Left` [[akka.actor.ActorTimeoutException]]. + * is completed with failure [[akka.actor.ActorTimeoutException]]. */ def gracefulStop(target: ActorRef, timeout: Duration)(implicit system: ActorSystem): Future[Boolean] = { if (target.isTerminated) { diff --git a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java index d442ae6461..b1d84a5841 100644 --- a/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java +++ b/akka-docs/java/code/akka/docs/actor/UntypedActorDocTestBase.java @@ -28,6 +28,14 @@ import akka.japi.Procedure; import akka.actor.Terminated; //#import-watch +//#import-gracefulStop +import static akka.pattern.Patterns.gracefulStop; +import akka.dispatch.Future; +import akka.dispatch.Await; +import akka.util.Duration; +import akka.actor.ActorTimeoutException; +//#import-gracefulStop + import akka.actor.Props; import akka.actor.UntypedActor; import akka.actor.UntypedActorFactory; @@ -100,8 +108,7 @@ public class UntypedActorDocTestBase { public void propsActorOf() { ActorSystem system = ActorSystem.create("MySystem"); //#creating-props - ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"), - "myactor"); + ActorRef myActor = system.actorOf(new Props(MyUntypedActor.class).withDispatcher("my-dispatcher"), "myactor"); //#creating-props myActor.tell("test"); system.shutdown(); @@ -174,6 +181,23 @@ public class UntypedActorDocTestBase { system.shutdown(); } + @Test + public void usePatternsGracefulStop() { + ActorSystem system = ActorSystem.create("MySystem"); + ActorRef actorRef = system.actorOf(new Props(MyUntypedActor.class)); + //#gracefulStop + + try { + Future stopped = gracefulStop(actorRef, Duration.create(5, TimeUnit.SECONDS), system); + Await.result(stopped, Duration.create(6, TimeUnit.SECONDS)); + // the actor has been stopped + } catch (ActorTimeoutException e) { + // the actor wasn't stopped within 5 seconds + } + //#gracefulStop + system.shutdown(); + } + public static class MyActor extends UntypedActor { public MyActor(String s) { @@ -264,6 +288,7 @@ public class UntypedActorDocTestBase { } } } + //#hot-swap-actor //#watch diff --git a/akka-docs/java/untyped-actors.rst b/akka-docs/java/untyped-actors.rst index b24b1d6e6c..7e0d788590 100644 --- a/akka-docs/java/untyped-actors.rst +++ b/akka-docs/java/untyped-actors.rst @@ -485,6 +485,16 @@ Use it like this: .. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java :include: import-actors,poison-pill +Graceful Stop +------------- + +:meth:`gracefulStop` is useful if you need to wait for termination or compose ordered +termination of several actors: + +.. includecode:: code/akka/docs/actor/UntypedActorDocTestBase.java + :include: import-gracefulStop,gracefulStop + + .. _UntypedActor.HotSwap: HotSwap diff --git a/akka-docs/scala/actors.rst b/akka-docs/scala/actors.rst index 204aa3ce56..558b50fac8 100644 --- a/akka-docs/scala/actors.rst +++ b/akka-docs/scala/actors.rst @@ -538,6 +538,15 @@ stop the actor when the message is processed. ``PoisonPill`` is enqueued as ordinary messages and will be handled after messages that were already queued in the mailbox. +Graceful Stop +------------- + +:meth:`gracefulStop` is useful if you need to wait for termination or compose ordered +termination of several actors: + +.. includecode:: code/akka/docs/actor/ActorDocSpec.scala#gracefulStop + + .. _Actor.HotSwap: Become/Unbecome diff --git a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala index cdba3d07f3..20ac33480b 100644 --- a/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala +++ b/akka-docs/scala/code/akka/docs/actor/ActorDocSpec.scala @@ -8,13 +8,7 @@ import akka.actor.Actor import akka.actor.Props import akka.event.Logging import akka.dispatch.Future - -//#imports1 - -//#imports2 import akka.actor.ActorSystem -//#imports2 - import org.scalatest.{ BeforeAndAfterAll, WordSpec } import org.scalatest.matchers.MustMatchers import akka.testkit._ @@ -114,7 +108,6 @@ object SwapperApp extends App { //#swapper //#receive-orElse -import akka.actor.Actor.Receive abstract class GenericActor extends Actor { // to be defined in subclassing actor @@ -317,4 +310,22 @@ class ActorDocSpec extends AkkaSpec(Map("akka.loglevel" -> "INFO")) { a ! "kill" expectMsg("finished") } + + "using pattern gracefulStop" in { + val actorRef = system.actorOf(Props[MyActor]) + //#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 + } + //#gracefulStop + + } }