Reputation: 6599
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
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