Update: I got it to work as expected (expected by me, at least):
whenUnhandled {
case event@Event(message, _) =>
unhandled(message)
stop(Failure(s"Unhandled message $message in state $stateName"))
}
and the test:
it should "not handle X in state Y" in {
system.eventStream.subscribe(testActor, classOf[UnhandledMessage])
actor.setState(Y, Z)
actor ! X
expectMsgType[UnhandledMessage](1 seconds)
}
In my case the *stop()* is a bit redundant, since the supervisor will
restart the actor anyway on an *UnhandledMessage*. But hey, a *stay()* is
equally weird.
It would be nice if the default behavior of FSM would be *unhandled(message);
stay()*. That seems to me to integrate better with actor supervisor
strategies. My 2 cents. =)
Yours,
Jasper
On Sunday, August 30, 2015 at 12:46:33 AM UTC+2, Jasper Visser wrote:
>
> Hi,
>
> I have a parent actor and some child actors; most are subclasses of
> *akka.actor.FSM*, some are simply *akka.actor.Actor*. The parent actor
> has a *AllForOneStrategy* to restart all the child actors on any
> unhandled exception. This seems to work as advertised.
>
> I would like to have it so that when a child actor receives an *unhandled
> event*, this will also trigger the supervisor strategy. Basically, any
> unhandled event would result in a restart of all the children. It's
> probably a sledgehammer approach, but I can always finetune it later.
>
> Unfortunately (for what I have in mind, at least) the default behavior of
> FSM on unhandled events is to *log a warning *and* stay()*. On the other
> hand, the default behavior of Actor is to publish an *UnhandledMessage* or
> throw *DeathPactException*.
>
> Is there a simple way to get FSM to behave the same way as Actor?
>
> I tried this approach:
> whenUnhandled {
> case event@Event(_, _) =>
> log.error(s"Unhandled event $event")
> unhandled(event)
> stay()
> }
> But that doesn't seem to do anything. The parent never receives the
> *UnhandledMessage* message.
>
> I can trigger the supervisor strategy by simply throwing an exception:
> whenUnhandled {
> case event@Event(_, _) =>
> log.error(s"Unhandled event $event")
> throw new RuntimeException(s"Unhandled event $event")
> }
> But in that scenario I have no idea how to unit test the case of an
> unhandled event.
>
> For that matter I can find very few examples of testing unhandled
> messages/events. Closest thing I've found is:
> http://doc.akka.io/docs/akka/2.0.5/scala/testing.html
> import akka.testkit.TestActorRef
> system.eventStream.subscribe(testActor, classOf[UnhandledMessage])
> val ref = TestActorRef[MyActor]
> ref.receive(Unknown)
> expectMsg(1 second, UnhandledMessage(Unknown, system.deadLetters, ref))
>
> So basically my questions are:
>
> 1. What is a good way to use a supervisor strategy in a system that
> includes FSM actors?
> 2. What is a good way to unit test unhandled events on FSM actors?
>
> Yours,
>
> Jasper
>
--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ:
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.