I'm started to learn Akka and in many official examples I see that request-response
implemented using tell
pattern. I.e. after worker made his work he sends result as new message back to sender. For example in this Pi approximation official tutorial shown how to design application where Master sends some work to workers and then awaits for results as another message.
Master code:
def receive = {
case Calculate ⇒
for (i ← 0 until nrOfMessages) workerRouter ! Work(i * nrOfElements, nrOfElements)
case Result(value) ⇒
pi += value
nrOfResults += 1
if (nrOfResults == nrOfMessages) {
// Send the result to the listener
listener ! PiApproximation(pi, duration = (System.currentTimeMillis - start).millis)
// Stops this actor and all its supervised children
context.stop(self)
}
}
Worker code:
def receive = {
case Work(start, nrOfElements) ⇒
sender ! Result(calculatePiFor(start, nrOfElements)) // perform the work
}
But I'm wondering why this example didn't use ask pattern? What is wrong with using ask pattern here?
If it's ok to use ask pattern here, then I have another question: how I can stop all worker actors after work is done?
PoisonPill
message to themselves?Broadcast(PoisonPill)
?ask
is useful when integrating actors with Future
APIs, but they do introduce some overhead. Further, Future
completions do not come through an actor's mailbox and are scheduled on a thread separate from the one used by the mailbox, meaning that receiving a future completion inside an actor introduces the need for doing multi-thread coordination.
Meanwhile, if you use tell
to send to a worker and have it tell
the sender
in response, the communication will always flow properly through the mailbox channel.
Additionally, it is much easier to discern the inputs an actor deals with if they all come in via receive
rather than some coming in via receive
and other's as completions of ask
messages.
To address you PoisonPill
questions, the answer is likely depends. You might opt for a worker-per-message approach in which case the worker should kill itself. If instead you use a worker pool, you could make the supervisor responsible for scaling that pool up and down, having it send the PoisonPill
or have workers time out on idleness, once again killing themselves.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With