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 java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
|
import akka.actor.ActorInitializationException
|
||||||
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
import akka.actor.testkit.typed.scaladsl.ScalaTestWithActorTestKit
|
||||||
import akka.actor.testkit.typed.scaladsl.TestProbe
|
import akka.actor.testkit.typed.scaladsl.TestProbe
|
||||||
import akka.actor.typed.scaladsl.Behaviors
|
import akka.actor.typed.scaladsl.Behaviors
|
||||||
|
import akka.actor.typed.scaladsl.adapter._
|
||||||
|
import akka.testkit.EventFilter
|
||||||
import org.scalatest.WordSpecLike
|
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] = {
|
def intToString(probe: ActorRef[String]): Behavior[Int] = {
|
||||||
Behaviors.receiveMessage[String] { msg ⇒
|
Behaviors.receiveMessage[String] { msg ⇒
|
||||||
|
|
@ -36,11 +46,14 @@ class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
||||||
val probe = TestProbe[String]()
|
val probe = TestProbe[String]()
|
||||||
val ref = spawn(intToString(probe.ref))
|
val ref = spawn(intToString(probe.ref))
|
||||||
|
|
||||||
ref ! 42
|
// TestEventListener logs unhandled as warnings, silence that
|
||||||
ref ! 13
|
EventFilter.warning(occurrences = 1).intercept {
|
||||||
ref ! 43
|
ref ! 42
|
||||||
probe.expectMessage("42")
|
ref ! 13
|
||||||
probe.expectMessage("43")
|
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 {
|
||||||
|
|
@ -105,6 +118,30 @@ class WidenSpec extends ScalaTestWithActorTestKit with WordSpecLike {
|
||||||
transformCount.get should ===(2)
|
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._
|
import BehaviorInterceptor._
|
||||||
|
|
||||||
override def isSame(other: BehaviorInterceptor[Any, Any]): Boolean = other match {
|
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 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] = {
|
def aroundReceive(ctx: ActorContext[O], msg: O, target: ReceiveTarget[I]): Behavior[I] = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue