Some more BehaviorIntercept tests
* filter messages * show how it can be used to implement PoisonPill
This commit is contained in:
parent
e62240b4b3
commit
af2d15a188
2 changed files with 65 additions and 11 deletions
|
|
@ -7,20 +7,25 @@ package akka.actor.typed
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
import akka.testkit.EventFilter
|
import akka.testkit.EventFilter
|
||||||
import akka.actor.testkit.typed.scaladsl.{ ActorTestKit, TestProbe }
|
import akka.actor.testkit.typed.scaladsl.TestProbe
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
import org.scalatest.WordSpecLike
|
import org.scalatest.WordSpecLike
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
import akka.actor.ActorInitializationException
|
import akka.actor.ActorInitializationException
|
||||||
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
||||||
import com.typesafe.config.ConfigFactory
|
|
||||||
|
object InterceptSpec {
|
||||||
|
final case class Msg(hello: String, replyTo: ActorRef[String])
|
||||||
|
case object MyPoisonPill
|
||||||
|
}
|
||||||
|
|
||||||
class InterceptSpec extends ScalaTestWithActorTestKit(
|
class InterceptSpec extends ScalaTestWithActorTestKit(
|
||||||
"""
|
"""
|
||||||
akka.loggers = [akka.testkit.TestEventListener]
|
akka.loggers = [akka.testkit.TestEventListener]
|
||||||
""") with WordSpecLike {
|
""") with WordSpecLike {
|
||||||
import BehaviorInterceptor._
|
import BehaviorInterceptor._
|
||||||
|
import InterceptSpec._
|
||||||
|
|
||||||
// FIXME eventfilter support in typed testkit
|
// FIXME eventfilter support in typed testkit
|
||||||
import scaladsl.adapter._
|
import scaladsl.adapter._
|
||||||
|
|
@ -268,4 +273,40 @@ class InterceptSpec extends ScalaTestWithActorTestKit(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"be useful for implementing PoisonPill" in {
|
||||||
|
|
||||||
|
def inner(count: Int): Behavior[Msg] = Behaviors.receiveMessage {
|
||||||
|
case Msg(hello, replyTo) ⇒
|
||||||
|
replyTo ! s"$hello-$count"
|
||||||
|
inner(count + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
val poisonInterceptor = new BehaviorInterceptor[Any, Msg] {
|
||||||
|
override def aroundReceive(ctx: ActorContext[Any], msg: Any, target: ReceiveTarget[Msg]): Behavior[Msg] =
|
||||||
|
msg match {
|
||||||
|
case MyPoisonPill ⇒ Behaviors.stopped
|
||||||
|
case m: Msg ⇒ target(ctx, m)
|
||||||
|
case _ ⇒ Behaviors.unhandled
|
||||||
|
}
|
||||||
|
|
||||||
|
override def aroundSignal(ctx: ActorContext[Any], signal: Signal, target: SignalTarget[Msg]): Behavior[Msg] =
|
||||||
|
target.apply(ctx, signal)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
val decorated: Behavior[Msg] =
|
||||||
|
Behaviors.intercept(poisonInterceptor)(inner(0)).narrow
|
||||||
|
|
||||||
|
val ref = spawn(decorated)
|
||||||
|
val probe = TestProbe[String]()
|
||||||
|
ref ! Msg("hello", probe.ref)
|
||||||
|
probe.expectMessage("hello-0")
|
||||||
|
ref ! Msg("hello", probe.ref)
|
||||||
|
probe.expectMessage("hello-1")
|
||||||
|
|
||||||
|
ref.upcast[Any] ! MyPoisonPill
|
||||||
|
|
||||||
|
probe.expectTerminated(ref, probe.remainingOrDefault)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,23 +13,36 @@ import org.scalatest.WordSpecLike
|
||||||
|
|
||||||
class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
||||||
|
|
||||||
|
def intToString(probe: ActorRef[String]): Behavior[Int] = {
|
||||||
|
Behaviors.receiveMessage[String] { msg ⇒
|
||||||
|
probe ! msg
|
||||||
|
Behaviors.same
|
||||||
|
}.widen[Int] {
|
||||||
|
case n if n != 13 ⇒ n.toString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
"Widen" should {
|
"Widen" should {
|
||||||
|
|
||||||
"transform messages from an outer type to an inner type" in {
|
"transform from an outer type to an inner type" in {
|
||||||
val probe = TestProbe[String]()
|
val probe = TestProbe[String]()
|
||||||
val beh = Behaviors.receiveMessage[String] { msg ⇒
|
val ref = spawn(intToString(probe.ref))
|
||||||
probe.ref ! msg
|
|
||||||
Behaviors.same
|
|
||||||
}.widen[Int] {
|
|
||||||
case n ⇒ n.toString
|
|
||||||
}
|
|
||||||
val ref = spawn(beh)
|
|
||||||
|
|
||||||
ref ! 42
|
ref ! 42
|
||||||
|
|
||||||
probe.expectMessage("42")
|
probe.expectMessage("42")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"filter messages" in {
|
||||||
|
val probe = TestProbe[String]()
|
||||||
|
val ref = spawn(intToString(probe.ref))
|
||||||
|
|
||||||
|
ref ! 42
|
||||||
|
ref ! 13
|
||||||
|
ref ! 43
|
||||||
|
probe.expectMessage("42")
|
||||||
|
probe.expectMessage("43")
|
||||||
|
}
|
||||||
|
|
||||||
"not build up when the same widen is used many times (initially)" in {
|
"not build up when the same widen is used many times (initially)" in {
|
||||||
val probe = TestProbe[String]()
|
val probe = TestProbe[String]()
|
||||||
val transformCount = new AtomicInteger(0)
|
val transformCount = new AtomicInteger(0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue