3

I have two actors, one is producing messages and the other is consuming the messages at a fixed rate.

Is it possible to have the producer throttled by the consumers BoundedMailBox? (back pressure)

My producer is currently periodically scheduled (sending it a tick message), is there a way to have it scheduled by availability in the consumers mailbox instead?

I am using fire and forget style ( consumer.tell() ) since I do not need a response. Should I be using different message sending approach?

JeffV
  • 52,985
  • 32
  • 103
  • 124
  • 1
    Leaving technology aside for a bit, if the consumer and the producer each was a human being, how would they solve the same problem? – Viktor Klang May 11 '13 at 19:27
  • @ViktorKlang, I could implement a flow control channel from the consumer with a start / stop messages. However, sometimes flow control is built in such as with ZMQ PUSH/PULL channels. I'm looking for a high throughput / low latency pipeline architecture where messages will be ~4k and ~20k messages per second. So, I'd like to avoid a flow control feedback channel if possible. – JeffV May 11 '13 at 20:49
  • Without control feedback there cannot be any backpressure. – Viktor Klang May 11 '13 at 20:59
  • Ok, so flow control needs to be explicit channel. I'm trying to understand how this type of pipeline is normally implemented in akka. Also, what happens when a BoundedMailBox is written to when it is at its bound (full)? (is the message dropped?) – JeffV May 11 '13 at 21:08
  • 3
    It blocks the calling thread for at most "mailbox-push-timeout-time" time and then it goes into DeadLetters. I don't recommend using bounded mailboxes as both latency and throughput will suffer and you risk deadlocks etc. Use a pull or ack-based approach for flow control. – Viktor Klang May 11 '13 at 21:45
  • This blog post might be of interest http://letitcrash.com/post/28901663062/throttling-messages-in-akka-2 – cmbaxter May 15 '13 at 11:17

1 Answers1

-1

Just specify a mailbox limit and it appears to block if the mailbox is full. I haven't tried this myself but the guys in this thread were looking at the behaviour and both found that the actor just blocks once the mailbox is at the limit.

See here for discussion and more testing of this nature. https://groups.google.com/forum/?fromgroups=#!topic/akka-user/e0tebq5V4nM

From that thread:

object ProducerConsumer extends App {

  implicit val system = ActorSystem("ProducerConsumer")

  def waitFor(actor: ActorRef) {
    Await.ready(gracefulStop(actor, 5.seconds), 5.seconds)
  }

  val consumers = system.actorOf(Props[Consumer].
    withRouter(RoundRobinRouter(4)).
    withDispatcher("consumer-dispatcher"), "consumer")

  for (work <- generateWork)
    consumers ! work

  consumers ! PoisonPill
  waitFor(consumers)
  system.shutdown
}

application.conf:

consumer-dispatcher {
  type = BalancingDispatcher
  mailbox-capacity = 100
}
JasonG
  • 5,794
  • 4
  • 39
  • 67