Behavior.orElse start the other behavior (#25977)
* Behavior.orElse start the other behavior * Finalize the case classes
This commit is contained in:
parent
e9fb3a020a
commit
f1b9adb0c4
4 changed files with 98 additions and 10 deletions
|
|
@ -6,14 +6,16 @@ package akka.actor.typed
|
|||
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import akka.actor.testkit.typed.scaladsl._
|
||||
import org.scalatest.Matchers
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.{ Matchers, WordSpec, WordSpecLike }
|
||||
|
||||
object OrElseStubbedSpec {
|
||||
|
||||
object OrElseSpec {
|
||||
sealed trait Ping
|
||||
case class Ping1(replyTo: ActorRef[Pong]) extends Ping
|
||||
case class Ping2(replyTo: ActorRef[Pong]) extends Ping
|
||||
case class Ping3(replyTo: ActorRef[Pong]) extends Ping
|
||||
final case class Ping1(replyTo: ActorRef[Pong]) extends Ping
|
||||
final case class Ping2(replyTo: ActorRef[Pong]) extends Ping
|
||||
final case class Ping3(replyTo: ActorRef[Pong]) extends Ping
|
||||
final case class PingInfinite(replyTo: ActorRef[Pong]) extends Ping
|
||||
|
||||
case class Pong(counter: Int)
|
||||
|
||||
def ping(counters: Map[String, Int]): Behavior[Ping] = {
|
||||
|
|
@ -45,9 +47,9 @@ object OrElseSpec {
|
|||
|
||||
}
|
||||
|
||||
class OrElseSpec extends WordSpec with Matchers {
|
||||
class OrElseStubbedSpec extends WordSpec with Matchers {
|
||||
|
||||
import OrElseSpec._
|
||||
import OrElseStubbedSpec._
|
||||
|
||||
"Behavior.orElse" must {
|
||||
|
||||
|
|
@ -71,6 +73,88 @@ class OrElseSpec extends WordSpec with Matchers {
|
|||
testkit.run(Ping1(inbox.ref))
|
||||
inbox.receiveMessage() should ===(Pong(3))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class OrElseSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
||||
|
||||
import OrElseStubbedSpec._
|
||||
|
||||
"Behavior.orElse" must {
|
||||
"work for deferred behavior on the left" in {
|
||||
val orElseDeferred = Behaviors.setup[Ping] { _ ⇒
|
||||
Behaviors.receiveMessage { _ ⇒
|
||||
Behaviors.unhandled
|
||||
}
|
||||
}.orElse(ping(Map.empty))
|
||||
|
||||
val p = spawn(orElseDeferred)
|
||||
val probe = TestProbe[Pong]
|
||||
p ! Ping1(probe.ref)
|
||||
probe.expectMessage(Pong(1))
|
||||
|
||||
}
|
||||
|
||||
"work for deferred behavior on the right" in {
|
||||
val orElseDeferred = ping(Map.empty).orElse(Behaviors.setup { _ ⇒
|
||||
Behaviors.receiveMessage {
|
||||
case PingInfinite(replyTo) ⇒
|
||||
replyTo ! Pong(-1)
|
||||
Behaviors.same
|
||||
}
|
||||
})
|
||||
|
||||
val p = spawn(orElseDeferred)
|
||||
val probe = TestProbe[Pong]
|
||||
p ! PingInfinite(probe.ref)
|
||||
probe.expectMessage(Pong(-1))
|
||||
}
|
||||
}
|
||||
|
||||
"handle nested OrElse" in {
|
||||
|
||||
sealed trait Parent
|
||||
final case class Add(o: Any) extends Parent
|
||||
final case class Remove(o: Any) extends Parent
|
||||
final case class Stack(s: ActorRef[Array[StackTraceElement]]) extends Parent
|
||||
final case class Get(s: ActorRef[Set[Any]]) extends Parent
|
||||
|
||||
def dealer(set: Set[Any]): Behavior[Parent] = {
|
||||
val add = Behaviors.receiveMessage[Parent] {
|
||||
case Add(o) ⇒ dealer(set + o)
|
||||
case _ ⇒ Behaviors.unhandled
|
||||
}
|
||||
val remove = Behaviors.receiveMessage[Parent] {
|
||||
case Remove(o) ⇒ dealer(set - o)
|
||||
case _ ⇒ Behaviors.unhandled
|
||||
}
|
||||
val getStack = Behaviors.receiveMessagePartial[Parent] {
|
||||
case Stack(sender) ⇒
|
||||
sender ! Thread.currentThread().getStackTrace
|
||||
Behaviors.same
|
||||
}
|
||||
val getSet = Behaviors.receiveMessagePartial[Parent] {
|
||||
case Get(sender) ⇒
|
||||
sender ! set
|
||||
Behaviors.same
|
||||
}
|
||||
add.orElse(remove).orElse(getStack).orElse(getSet)
|
||||
}
|
||||
|
||||
val y = spawn(dealer(Set.empty))
|
||||
|
||||
(0 to 10000) foreach { i ⇒
|
||||
y ! Add(i)
|
||||
}
|
||||
(0 to 9999) foreach { i ⇒
|
||||
y ! Remove(i)
|
||||
}
|
||||
val probe = TestProbe[Set[Any]]
|
||||
y ! Get(probe.ref)
|
||||
probe.expectMessage(Set[Any](10000))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ package akka.actor.typed
|
|||
|
||||
import akka.actor.InvalidMessageException
|
||||
import akka.actor.typed.internal.BehaviorImpl
|
||||
import scala.annotation.tailrec
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import akka.actor.typed.internal.BehaviorImpl.OrElseBehavior
|
||||
import akka.actor.typed.internal.WrappingBehavior
|
||||
import akka.util.{ LineNumbers, OptionVal }
|
||||
|
|
@ -51,7 +51,9 @@ sealed abstract class Behavior[T] { behavior ⇒
|
|||
*
|
||||
* @param that the fallback `Behavior`
|
||||
*/
|
||||
final def orElse(that: Behavior[T]): Behavior[T] = new OrElseBehavior[T](this, that)
|
||||
final def orElse(that: Behavior[T]): Behavior[T] = Behavior.DeferredBehavior[T] { ctx ⇒
|
||||
new OrElseBehavior[T](Behavior.start(this, ctx), Behavior.start(that, ctx))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ import akka.actor.typed.scaladsl.{ ActorContext ⇒ SAC }
|
|||
InterceptorImpl(interceptor, behavior)
|
||||
|
||||
class OrElseBehavior[T](first: Behavior[T], second: Behavior[T]) extends ExtensibleBehavior[T] {
|
||||
|
||||
override def receive(ctx: AC[T], msg: T): Behavior[T] = {
|
||||
Behavior.interpretMessage(first, ctx, msg) match {
|
||||
case _: UnhandledBehavior.type ⇒ Behavior.interpretMessage(second, ctx, msg)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import java.util.concurrent.TimeUnit
|
|||
import scala.concurrent.ExecutionContext
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.Promise
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import akka.Done
|
||||
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue