From f4fbbf93120f33c186a3b2ca70b22e3e6c72ca05 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Thu, 19 Jul 2018 10:26:01 +0900 Subject: [PATCH] =typ #24725 disallow deferred behaviors as postStop hooks (#25123) --- .../akka/actor/typed/scaladsl/StopSpec.scala | 21 +++++++++++++++++-- .../scala/akka/actor/typed/Behavior.scala | 18 +++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StopSpec.scala b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StopSpec.scala index 403b3638fe..91cb15f1b6 100644 --- a/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StopSpec.scala +++ b/akka-actor-typed-tests/src/test/scala/akka/actor/typed/scaladsl/StopSpec.scala @@ -5,8 +5,10 @@ package akka.actor.typed.scaladsl import akka.Done -import akka.actor.typed.{ PostStop, TypedAkkaSpecWithShutdown } -import akka.actor.testkit.typed.scaladsl.ActorTestKit +import akka.actor.testkit.typed.TE +import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, TestProbe } +import akka.actor.typed.{ Behavior, PostStop, SupervisorStrategy, Terminated, TypedAkkaSpecWithShutdown } +import akka.testkit.EventFilter import scala.concurrent.Promise @@ -58,4 +60,19 @@ class StopSpec extends ActorTestKit with TypedAkkaSpecWithShutdown { } + "PostStop" should { + "immediately throw when a deferred behavior (setup) is passed in as postStop" in { + val ex = intercept[IllegalArgumentException] { + Behaviors.stopped( + // illegal: + Behaviors.setup[String] { _ ⇒ + throw TE("boom!") + } + ) + } + + ex.getMessage should include("Behavior used as `postStop` behavior in Stopped(...) was a deferred one ") + } + } + } diff --git a/akka-actor-typed/src/main/scala/akka/actor/typed/Behavior.scala b/akka-actor-typed/src/main/scala/akka/actor/typed/Behavior.scala index 5a47ed902c..0f22ba147c 100644 --- a/akka-actor-typed/src/main/scala/akka/actor/typed/Behavior.scala +++ b/akka-actor-typed/src/main/scala/akka/actor/typed/Behavior.scala @@ -233,7 +233,23 @@ object Behavior { * that PostStop can be sent to previous behavior from `finishTerminate`. */ private[akka] class StoppedBehavior[T](val postStop: OptionVal[Behavior[T]]) extends Behavior[T] { - override def toString = "Stopped" + validatePostStop(postStop) + + @throws[IllegalArgumentException] + private final def validatePostStop(postStop: OptionVal[Behavior[T]]): Unit = { + postStop match { + case OptionVal.Some(b: DeferredBehavior[_]) ⇒ + throw new IllegalArgumentException(s"Behavior used as `postStop` behavior in Stopped(...) was a deferred one [${b.toString}], which is not supported (it would never be evaluated).") + case _ ⇒ // all good + } + } + + override def toString = "Stopped" + { + postStop match { + case OptionVal.Some(_) ⇒ "(postStop)" + case _ ⇒ "()" + } + } } /**