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 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 org.scalatest.WordSpecLike
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.actor.ActorInitializationException
|
||||
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(
|
||||
"""
|
||||
akka.loggers = [akka.testkit.TestEventListener]
|
||||
""") with WordSpecLike {
|
||||
import BehaviorInterceptor._
|
||||
import InterceptSpec._
|
||||
|
||||
// FIXME eventfilter support in typed testkit
|
||||
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 {
|
||||
|
||||
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 {
|
||||
|
||||
"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 beh = Behaviors.receiveMessage[String] { msg ⇒
|
||||
probe.ref ! msg
|
||||
Behaviors.same
|
||||
}.widen[Int] {
|
||||
case n ⇒ n.toString
|
||||
}
|
||||
val ref = spawn(beh)
|
||||
val ref = spawn(intToString(probe.ref))
|
||||
|
||||
ref ! 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 {
|
||||
val probe = TestProbe[String]()
|
||||
val transformCount = new AtomicInteger(0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue