Disallow nested mixed widen usages, #25604
This commit is contained in:
parent
63e00634d4
commit
8c058678ca
2 changed files with 50 additions and 8 deletions
|
|
@ -6,12 +6,22 @@ package akka.actor.typed
|
|||
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
import akka.actor.ActorInitializationException
|
||||
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
||||
import akka.actor.testkit.typed.scaladsl.TestProbe
|
||||
import akka.actor.typed.scaladsl.Behaviors
|
||||
import akka.actor.typed.scaladsl.adapter._
|
||||
import akka.testkit.EventFilter
|
||||
import org.scalatest.WordSpecLike
|
||||
|
||||
class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
||||
import scala.concurrent.duration._
|
||||
|
||||
class WidenSpec extends ScalaTestWithActorTestKit(
|
||||
"""
|
||||
akka.loggers = [akka.testkit.TestEventListener]
|
||||
""") with WordSpecLike {
|
||||
|
||||
implicit val untypedSystem = system.toUntyped
|
||||
|
||||
def intToString(probe: ActorRef[String]): Behavior[Int] = {
|
||||
Behaviors.receiveMessage[String] { msg ⇒
|
||||
|
|
@ -36,11 +46,14 @@ class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
|||
val probe = TestProbe[String]()
|
||||
val ref = spawn(intToString(probe.ref))
|
||||
|
||||
ref ! 42
|
||||
ref ! 13
|
||||
ref ! 43
|
||||
probe.expectMessage("42")
|
||||
probe.expectMessage("43")
|
||||
// TestEventListener logs unhandled as warnings, silence that
|
||||
EventFilter.warning(occurrences = 1).intercept {
|
||||
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 {
|
||||
|
|
@ -105,6 +118,30 @@ class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
|||
transformCount.get should ===(2)
|
||||
|
||||
}
|
||||
|
||||
"not allow mixing different widens in the same behavior stack" in {
|
||||
val probe = TestProbe[String]()
|
||||
|
||||
def widen(behavior: Behavior[String]): Behavior[String] =
|
||||
behavior.widen[String] {
|
||||
case s ⇒ s.toLowerCase
|
||||
}
|
||||
|
||||
EventFilter[ActorInitializationException](occurrences = 1).intercept {
|
||||
val ref = spawn(
|
||||
widen(
|
||||
widen(
|
||||
Behaviors.receiveMessage[String] { msg ⇒
|
||||
Behaviors.same
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
probe.expectTerminated(ref, 3.seconds)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,9 +138,14 @@ private[akka] final case class WidenedInterceptor[O, I](matcher: PartialFunction
|
|||
import BehaviorInterceptor._
|
||||
|
||||
override def isSame(other: BehaviorInterceptor[Any, Any]): Boolean = other match {
|
||||
// can only be elimintated if it is the same partial function
|
||||
// If they use the same pf instance we can allow it, to have one way to workaround defining
|
||||
// "recursive" narrowed behaviors.
|
||||
case WidenedInterceptor(`matcher`) ⇒ true
|
||||
case _ ⇒ false
|
||||
case WidenedInterceptor(otherMatcher) ⇒
|
||||
// there is no safe way to allow this
|
||||
throw new IllegalStateException("Widen can only be used one time in the same behavior stack. " +
|
||||
s"One defined in ${LineNumbers(matcher)}, and another in ${LineNumbers(otherMatcher)}")
|
||||
case _ ⇒ false
|
||||
}
|
||||
|
||||
def aroundReceive(ctx: ActorContext[O], msg: O, target: ReceiveTarget[I]): Behavior[I] = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue