xiefei
xiefei

Reputation: 6599

How do I control flow with Akka?

I have read that an important rule when using Akka is avoiding any blocking input/output operations, polling, busy waiting, sleeping, etc. But what if I really need some flow control?

I am using Akka actors to send mail to our customers, and to be friendly to the mail server, send one mail per 5 second. My plan is using a dispatcher actor to do the flow control and a sender actor to do the mail sending work.

class Dispatcher extends Actor {
  def receive = {
    case ResetPassword(to, data) => 
      senderActor ! Mail("resetPassword", to, data)
      Thread.sleep(5000)
    ...
  }
}
class Sender extends Actor {
  def receive = {
    case Mail(to, data) => // send the mail immediately
    ...
  }
}

Is this the right way to go? If not, how should I do the flow control?

Upvotes: 0

Views: 651

Answers (1)

Ratan Sebastian
Ratan Sebastian

Reputation: 1892

One way to do this without blocking is to have another actor that holds the outbox state at any time.

class Outbox extends Actor {

  var outbox: List[Mail] = Nil  

  def receive = {
    case a: Mail => {
      outbox = outbox :+ a
    }

    case MailToSend => {
      val maybeMailToSend = outbox.headOption
      outbox = outbox.tail
      senderActor ! maybeMailToSend
    }
  }
}

Then have the Sender actor be a scheduled actor that polls the outbox every 5 seconds. It sends an ask MailToSend message to the Outbox actor and sends out the one mail if the response is a Some.

It would look something like this:

Scheduling the Sender actor:

system.scheduler.scheduleOnce(5 seconds, senderActor, PollOutbox)

Sender Actor:

class Sender extends Actor {
  def receive = {
    case PollOutbox => {
      maybeMailToSend = outboxActor ? MailToSend
      ...
    }
  }
}

Upvotes: 7

Related Questions