Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Akka Message Delivery Guarantees

Tags:

akka

I am trying to find out what message delivery guarantees Akka supports. I came to the following conclusion:

At-most-once : Supported by default

At-least-once : Supported with Akka Persistence

Exactly-once : ?

Does Akka support exactly-once? How would I be able to achieve this if it doesn't?

like image 984
stefana Avatar asked Mar 16 '15 10:03

stefana


People also ask

Does Akka guarantee the Order in which messages are enqueued?

It is important to note that Akka’s guarantee applies to the order in which messages are enqueued into the recipient’s mailbox. If the mailbox implementation does not respect FIFO order (e.g. a PriorityMailbox ), then the order of processing by the actor can deviate from the enqueueing order.

What is Akka and how does it work?

Akka embraces distributed computing and makes the fallibility of communication explicit through message passing, therefore it does not try to lie and emulate a leaky abstraction. This is a model that has been used with great success in Erlang and requires the users to design their applications around it.

What is transitive causal ordering in Akka?

The rule that for a given pair of actors, messages sent directly from the first to the second will not be received out-of-order holds for messages sent over the network with the TCP based Akka remote transport protocol. As explained in the previous section local message sends obey transitive causal ordering under certain conditions.

Is there a guarantee on the delivery of my messages?

Since there is no guaranteed delivery, any of the messages may be dropped, i.e. not arrive at A2 It is important to note that Akka’s guarantee applies to the order in which messages are enqueued into the recipient’s mailbox.


Video Answer


1 Answers

Akka out of the box provides At-Most-Once delivery, as you've discovered. At-Least-Once is available in some libraries such as Akka Persistence, and you can create it yourself fairly easily by creating an ACK-RETRY protocol in your actors. The Sender keeps periodically sending the message until the receiver acknowledges receipt of it.

Put simply, for At-Least-Once the responsibility is with the Sender. E.g in Scala:

class Sender(receiver: ActorRef) extends Actor {

  var acknowledged = false

  override def preStart() {
    receiver ! "Do Work"
    system.scheduler.scheduleOnce(50 milliseconds, self, "Retry")
  }

  def receive = {
    case "Retry" => 
      if(!acknowledged) {
        receiver ! "Do Work"
        system.scheduler.scheduleOnce(50 milliseconds, self, "Retry")
      }

    case "Ack" => acknowledged = true
  }
}

class Receiver extends Actor {

  def receive = {
    case "Do Work" => 
      doWork()
      sender ! "Ack"
  }

  def doWork() = {...}
}

But with At-Most-Once processing, the receiver has to ensure that repeated instances of the same message only result in work being done once. This could be achieved through making the work done by the receiver idempotent so it can be repeatedly applied, or by having the receiver keep a record of what it has processed already. For At-Most-Once the responsibility is with the receiver:

class AtMostOnceReceiver extends Actor {

  var workDone = false

  def receive = {

    case "Do Work" =>
      if(!workDone) {
        doWork()
        workDone = true
      }
      sender ! Ack
  }

}
like image 78
mattinbits Avatar answered Oct 11 '22 14:10

mattinbits