Widen and timers can be used together, #25318 (#27128)

* because timers are not implemented with interceptor any more,
  https://github.com/akka/akka/pull/26650
This commit is contained in:
Patrik Nordwall 2019-06-13 15:11:06 +02:00 committed by Helena Edelson
parent 231f0d6bb1
commit f004a574b4
4 changed files with 49 additions and 15 deletions

View file

@ -123,7 +123,7 @@ class WidenSpec extends ScalaTestWithActorTestKit("""
}
EventFilter[ActorInitializationException](occurrences = 1).intercept {
val ref = spawn(widen(widen(Behaviors.receiveMessage[String] { message =>
val ref = spawn(widen(widen(Behaviors.receiveMessage[String] { _ =>
Behaviors.same
})))
@ -131,6 +131,50 @@ class WidenSpec extends ScalaTestWithActorTestKit("""
}
}
"be possible to combine with inner timers" in {
val probe = TestProbe[String]()
val behv = Behaviors
.withTimers[String] { timers =>
timers.startSingleTimer("timer", "a", 10.millis)
Behaviors.receiveMessage { msg =>
probe.ref ! msg
Behaviors.same
}
}
.widen[String] {
case msg => msg.toUpperCase()
}
val ref = spawn(behv)
probe.expectMessage("A")
ref ! "b"
probe.expectMessage("B")
}
"be possible to combine with outer timers" in {
val probe = TestProbe[String]()
val behv = Behaviors.withTimers[String] { timers =>
timers.startSingleTimer("timer", "a", 10.millis)
Behaviors
.receiveMessage[String] { msg =>
probe.ref ! msg
Behaviors.same
}
.widen[String] {
case msg => msg.toUpperCase()
}
}
val ref = spawn(behv)
probe.expectMessage("A")
ref ! "b"
probe.expectMessage("B")
}
}
}

View file

@ -134,8 +134,6 @@ object Behavior {
* }
* }}}
*
* Scheduled messages via [[akka.actor.typed.scaladsl.TimerScheduler]] can currently
* not be used together with `widen`, see issue #25318.
*/
def widen[U](matcher: PartialFunction[U, T]): Behavior[U] =
BehaviorImpl.widened(behavior, matcher)

View file

@ -5,9 +5,10 @@
package akka.actor.typed.internal
import akka.actor.typed
import akka.actor.typed.internal.TimerSchedulerImpl.TimerMsg
import akka.actor.typed.scaladsl.Behaviors
import akka.actor.typed.{ LogOptions, _ }
import akka.actor.typed.LogOptions
import akka.actor.typed._
import akka.annotation.InternalApi
import akka.util.LineNumbers
@ -179,8 +180,8 @@ private[akka] object WidenedInterceptor {
@InternalApi
private[akka] final case class WidenedInterceptor[O, I](matcher: PartialFunction[O, I])
extends BehaviorInterceptor[O, I] {
import WidenedInterceptor._
import BehaviorInterceptor._
import WidenedInterceptor._
override def isSame(other: BehaviorInterceptor[Any, Any]): Boolean = other match {
// If they use the same pf instance we can allow it, to have one way to workaround defining
@ -195,13 +196,6 @@ private[akka] final case class WidenedInterceptor[O, I](matcher: PartialFunction
}
def aroundReceive(ctx: TypedActorContext[O], msg: O, target: ReceiveTarget[I]): Behavior[I] = {
// widen would wrap the TimerMessage, which would be wrong, see issue #25318
msg match {
case t: TimerMsg =>
throw new IllegalArgumentException(s"Timers and widen can't be used together, [${t.key}]. See issue #25318")
case _ => ()
}
matcher.applyOrElse(msg, any2null) match {
case null => Behaviors.unhandled
case transformed => target(ctx, transformed)

View file

@ -267,8 +267,6 @@ object Behaviors {
* );
* }}}
*
* Scheduled messages via [[TimerScheduler]] can currently not be used
* together with `widen`, see issue #25318.
*
* @param behavior
* the behavior that will receive the selected messages