0

Akka Java here. I have two actors, Parent and Child, where the former is the parent of the latter. If Child throws a specific exception (say, an UnrulyTeenagerExcepton), then the behavior I am looking for is as follows:

  • The Parent saves a reference to the message that was being processed by Child when the exception was thrown; then
  • Child is restarted, and the persisted message is “played back” to the Child; but
  • If this save -> restart -> replay cycle happens three times, and the Child throws the UnrulyTeenagerException three times, then we SupervisorStrategy.escalate()

My best attempt thus far:

// Groovy pseudo-code
class ChildFailureDecider extends Function<Throwable,Directive> {
    int maxRetries = 3
    int numRetries = 0

    @Override
    Directive apply(Throwable childFailure) {
        if(childFailure instanceof UnrulyTeenagerException) {
            numRetries++

            if(numRetries <= maxRetries) {
                // TODO: #1 How to persist the message that caused the ‘childFailure’?

                return SupervisorStrategy.restart()

                // TODO: #2 How to ‘play back’ the persisted message to Child?
            }
        }

        SupervisorStrategy.escalate()
    }
}

But as you can see, I’m struggling with message persistence and play back. Any ideas? Java code samples greatly appreciated, Akka is tough enough without also having to learn Scala hieroglyphics!

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
smeeb
  • 27,777
  • 57
  • 250
  • 447
  • 1
    By 'persist' do you require the message to be written to disk, or just persist in the sense that it is captured in a variable inside the Parent? – mattinbits Aug 26 '15 at 13:28
  • Thanks @mattinbits (+1) - I *guess* by "persist" I mean whatever is accomplished by using the Akka-Persistence module and `UntypedPersistentActorWithAtLeastOnceDelivery`. However, admittedly, I don't fully understand how persistent actors work, and so perhaps they are different than the use case I am presenting here. At the end of the day, I just need Akka to save (somewhere) a message that failed while processing a child, restart the child, and then re-process that saved message on the restarted child. Thoughts? Thanks again! – smeeb Aug 26 '15 at 17:47

1 Answers1

1

Akka persistence is about recording events (not the same thing as messages) in a persistent way (e.g. to disk, or to a database) in a persistent way so that if your whole application terminates (such as a JVM crash or hardware failure), it is possible to rebuild the state of that actor on restart. In your case, you want to remember the message sent to a single actor and resend it when that actor is restarted due to a failure, so I don't think you need the persistence API in this case.

When an actor throws an exception, that exception is presented to the supervisor but the message that caused it is not. I don't think there is a built in way for this to be achieved. The supervisor can manage the rule of only restarting 3 times, by setting the supervision strategy with appropriate parameters: http://doc.akka.io/japi/akka/2.4-M3/akka/actor/OneForOneStrategy.html#OneForOneStrategy-int-scala.concurrent.duration.Duration-akka.japi.Function-

The replaying of messages needs to be handled by the sender. You can implement at least once semantics by having the receiver send an acknowledgement to the sender when the message has been handled, and have the sender retry periodically if the acknowledgement is not received. See this question for more info: Akka Message Delivery Guarantees

Sorry for the lack of code but I use the Scala API rather than Java.

Community
  • 1
  • 1
mattinbits
  • 10,370
  • 1
  • 26
  • 35
  • Thanks @mattinbits (+1) - that makes sense. Regarding persistent actors, just curious here, under what sort of use cases would you want to rebuild the exact state of an actor? To me this feels a lot like [event sourcing](http://martinfowler.com/eaaDev/EventSourcing.html), and the only use case for event sourcing actor states, that I can think of, is for troubleshooting production issues. Thoughts? Thanks again! – smeeb Aug 27 '15 at 20:59
  • 1
    It's a lot like event sourcing, quoting the akka persistence docs `Akka persistence is inspired by and the official replacement of the eventsourced library` :) I'm not an expert on the use-cases, in the simplest case it can add robustness to your application since state can survive restarts but of course you could achieve this with regular database functionality. But an event log allows you to perform analysis on the history of the system, which is useful in more cases than just troubleshooting. – mattinbits Aug 27 '15 at 22:11