2

I am coming to Akka after spending quite a bit of time over in Hystrix-land where, like Akka, failure is a first-class citizen.

In Hystrix, I might have a SaveFizzToDbCmd that attempts to save a Fizz instance to an RDB (MySQL, whatever), and a backup/“fallbackSaveFizzToMemoryCmd that saves that Fizz to an in-memory cache in case the primary (DB) command goes down/starts failing:

// Groovy pseudo-code
class SaveFizzToDbCmd extends HystrixCommand<Fizz> {
    SaveFizzToMemoryCmd memoryFallback
    Fizz fizz

    @Override
    Fizz run() {
        // Use raw JDBC to save ‘fizz’ to an RDB.
    }

    @Override
    Fizz getFallback() {
        // This only executes if the ‘run()’ method above throws
        // an exception.
        memoryFallback.fizz = this.fizz
        memoryFallback.execute()
    }
}

In Hystrix, if run() throws an exception (say a SqlException), its getFallback() method is invoked. If enough exceptions get thrown within a certain amount of time, the HystrixCommands “circuit breaker” is “tripped” and only the getFallback() method will be invoked.

I am interested in accomplishing the same in Akka, but with actors. With Akka, we might have a JdbcPersistor actor and an InMemoryPersistor backup/fallback actor like so:

class JdbcPersistor extends UntypedActor {
    @Override
    void onReceive(Object message) {
        if(message instanceof SaveFizz) {
            SaveFizz saveFizz = message as SaveFizz
            Fizz fizz = saveFizz.fizz

            // Use raw JDBC to save ‘fizz’ to an RDB.
        }
    }
}

class InMemoryPersistor extends UntypedActor {
    // Should be obvious what this does.
}

The problem I’m struggling with is:

  • How to get InMemoryPeristor correctly configured/wired as the backup to JdbcPersistor when it is failing; and
  • Failing back over to the JdbcPersistor if/when it “heals” (though it may never)

I would imagine this is logic that belongs inside JdbcPersistors SupervisorStrategy, but I can find nothing in the Akka docs nor any code snippets that implement this kind of behavior. Which tells me “hey, maybe this isn’t the way Akka works, and perhaps there’s a different way of doing this sort of circuit breaking/failover/failback in Akka-land.” Thoughts?

Please note: Java examples are enormously appreciated as Scala looks like hieroglyphics to me!

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
smeeb
  • 27,777
  • 57
  • 250
  • 447

1 Answers1

0

One way would be to have a FailoverPersistor actor which consuming code communicates with, that has both a JdbcPersistor and a InMemoryPeristor as children and a flag that decides which one to use and then basically routes traffic to the correct child depending on the state. The flag could then be manipulated by both the supervisor and timed logic/statistics inside the actor.

There is a circuit breaker in the contrib package of akka that might be an inspiration (or maybe even useable to achieve what you want): http://doc.akka.io/docs/akka/current/common/circuitbreaker.html

johanandren
  • 11,249
  • 1
  • 25
  • 30