Throttling in Akka and Spray
When you want to limit the amount of messages an actor gets, you can use the throttler in akka-contrib. This will let you limit the max transactions per second(tps). It will queue up the surplus. Here I'll describe another way. I'll reject all the surplus messages. This has the advantage that the requester knows it's sending too much and can act on that. Both methods have their advantages. And both have limits, since they still require resources to queue or reject the messages. In Akka we can create an Actor that sends messages through to the target actor, or rejects them when it exceeds the specified tps.
object ThrottleActor {
object OneSecondLater
object Accepted
object ExceededMaxTps
}
import ThrottleActor._
class ThrottleActor (target: ActorRef, maxTps: Int) extends Actor with ActorLogging {
implicit val executionContext: ExecutionContext = context.dispatcher
context.system.scheduler.schedule(1.second, 1.second, self, OneSecondLater)
var messagesThisSecond: Int = 0
def receive = {
case OneSecondLater =>
log.info(s"OneSecondLater ${DateTime.now} $messagesThisSecond requests.")
messagesThisSecond = 0
case message if messagesThisSecond >= maxTps =>
sender ! ExceededMaxTps
messagesThisSecond += 1
log.info(s"ExceededMaxTps ${DateTime.now} $messagesThisSecond requests.")
case message =>
sender ! Accepted
target ! message
messagesThisSecond += 1
}
}