=per #15937 Allow PersistentActor to be used as a stackable modification
* PersistentActor correctly calls `super.around*` and allows to be mixed into e.g. ActorSubscriber * Tests have been added on PersistentActor and Processor to verify the stackable behavior of `around*` and `pre*` methods * Delegation in Processor has been simplified
This commit is contained in:
parent
ad35be7de1
commit
4f52158b0a
4 changed files with 246 additions and 28 deletions
|
|
@ -13,6 +13,7 @@ import akka.testkit.EventFilter
|
|||
import akka.testkit.TestProbe
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import scala.util.Random
|
||||
import scala.util.control.NoStackTrace
|
||||
|
||||
object PersistentActorSpec {
|
||||
final case class Cmd(data: Any)
|
||||
|
|
@ -403,6 +404,95 @@ object PersistentActorSpec {
|
|||
}
|
||||
}
|
||||
|
||||
class StackableTestPersistentActor(val probe: ActorRef) extends StackableTestPersistentActor.BaseActor with PersistentActor with StackableTestPersistentActor.MixinActor {
|
||||
override def persistenceId: String = "StackableTestPersistentActor"
|
||||
|
||||
def receiveCommand = {
|
||||
case "restart" ⇒ throw new Exception("triggering restart") with NoStackTrace { override def toString = "Boom!" }
|
||||
}
|
||||
|
||||
def receiveRecover = {
|
||||
case _ ⇒ ()
|
||||
}
|
||||
|
||||
override def preStart(): Unit = {
|
||||
probe ! "preStart"
|
||||
super.preStart()
|
||||
}
|
||||
|
||||
override def postStop(): Unit = {
|
||||
probe ! "postStop"
|
||||
super.postStop()
|
||||
}
|
||||
|
||||
override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
|
||||
probe ! "preRestart"
|
||||
super.preRestart(reason, message)
|
||||
}
|
||||
|
||||
override def postRestart(reason: Throwable): Unit = {
|
||||
probe ! "postRestart"
|
||||
super.postRestart(reason)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object StackableTestPersistentActor {
|
||||
trait BaseActor extends Actor { this: StackableTestPersistentActor ⇒
|
||||
override protected[akka] def aroundPreStart() = {
|
||||
probe ! "base aroundPreStart"
|
||||
super.aroundPreStart()
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPostStop() = {
|
||||
probe ! "base aroundPostStop"
|
||||
super.aroundPostStop()
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPreRestart(reason: Throwable, message: Option[Any]) = {
|
||||
probe ! "base aroundPreRestart"
|
||||
super.aroundPreRestart(reason, message)
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPostRestart(reason: Throwable) = {
|
||||
probe ! "base aroundPostRestart"
|
||||
super.aroundPostRestart(reason)
|
||||
}
|
||||
|
||||
override protected[akka] def aroundReceive(receive: Receive, message: Any) = {
|
||||
probe ! "base aroundReceive"
|
||||
super.aroundReceive(receive, message)
|
||||
}
|
||||
}
|
||||
|
||||
trait MixinActor extends Actor { this: StackableTestPersistentActor ⇒
|
||||
override protected[akka] def aroundPreStart() = {
|
||||
probe ! "mixin aroundPreStart"
|
||||
super.aroundPreStart()
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPostStop() = {
|
||||
probe ! "mixin aroundPostStop"
|
||||
super.aroundPostStop()
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPreRestart(reason: Throwable, message: Option[Any]) = {
|
||||
probe ! "mixin aroundPreRestart"
|
||||
super.aroundPreRestart(reason, message)
|
||||
}
|
||||
|
||||
override protected[akka] def aroundPostRestart(reason: Throwable) = {
|
||||
probe ! "mixin aroundPostRestart"
|
||||
super.aroundPostRestart(reason)
|
||||
}
|
||||
|
||||
override protected[akka] def aroundReceive(receive: Receive, message: Any) = {
|
||||
if (message == "restart" && recoveryFinished) { probe ! "mixin aroundReceive" }
|
||||
super.aroundReceive(receive, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class PersistentActorSpec(config: Config) extends AkkaSpec(config) with PersistenceSpec with ImplicitSender {
|
||||
|
|
@ -770,7 +860,35 @@ abstract class PersistentActorSpec(config: Config) extends AkkaSpec(config) with
|
|||
processor2 ! GetState
|
||||
expectMsg(List("a-1", "a-2", "b-41", "b-42", "c-41", "c-42", RecoveryCompleted))
|
||||
}
|
||||
"be used as a stackable modification" in {
|
||||
val persistentActor = system.actorOf(Props(classOf[StackableTestPersistentActor], testActor))
|
||||
expectMsg("mixin aroundPreStart")
|
||||
expectMsg("base aroundPreStart")
|
||||
expectMsg("preStart")
|
||||
|
||||
persistentActor ! "restart"
|
||||
expectMsg("mixin aroundReceive")
|
||||
expectMsg("base aroundReceive")
|
||||
|
||||
expectMsg("mixin aroundPreRestart")
|
||||
expectMsg("base aroundPreRestart")
|
||||
expectMsg("preRestart")
|
||||
expectMsg("postStop")
|
||||
|
||||
expectMsg("mixin aroundPostRestart")
|
||||
expectMsg("base aroundPostRestart")
|
||||
expectMsg("postRestart")
|
||||
expectMsg("preStart")
|
||||
|
||||
persistentActor ! PoisonPill
|
||||
expectMsg("mixin aroundPostStop")
|
||||
expectMsg("base aroundPostStop")
|
||||
expectMsg("postStop")
|
||||
|
||||
expectNoMsg(100.millis)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class LeveldbPersistentActorSpec extends PersistentActorSpec(PersistenceSpec.config("leveldb", "LeveldbPersistentActorSpec"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue