Reputation: 1192
I'm an akka noob so apologies!
I'm playing around with a system that uses Spray and Akka. I'm using the following code snippet to send a message to another actor. It uses ask which, from what I understand will return a future which is resolved in "mapTo" and "map". I then return the result to the users using Sprays "complete" directive.
val response = (worker ? Create(json))
.mapTo[Ok]
.map(result => s"I got a response: ${result}")
.recover { case _ => "error" }
complete(response)
My question is, since this is a future, do I need to be worried about sending the correct response to the client? In some code samples I see examples where the actorRef to reply to is sent as part of the request...
// set reply to actor
val replyTo = sender() // important to not close over sender()
// create actor that collects replies from workers
val aggregator = context.actorOf(Props(
classOf[StatsAggregator], words.size, replyTo))
Then in the receiving actor...
replyTo ! SendResult
Should I be passing the "replyTo" actor as part of the request or is this all taken care of in the mapTo?
Thanks in advance!
Upvotes: 0
Views: 423
Reputation: 7275
The complete
directive will send back a response to http/https client of your service. You don't need to do more than that. Please note that your code swallows errors by making recover
on a future. Spray will treat it as a success and will return status code 200
.
The last and most importantly, your worker has to reply with Ok
message back like this.
class Worker extends Actor {
def receive: Receive = {
case Create(json) =>
//do some staff with json
sender() ! Ok // This Ok message will be passed in the future in spray route
}
}
The replyTo
idiom is needed only when worker uses Future internally to process the work load. As it in the following example
class Worker extends Actor {
def recieve: Recieve = {
case Create(json) =>
val future = Future{
//do some staff with json
}
val replyTo = sender()
future.onComplete {
case scala.util.Success(result) =>
replyTo ! Ok
case scala.util.Failure(ex) =>
replyTo ! akka.actor.Status.Failure(ex)
}
}
}
The replyTo
is needed to fix actual sender of the message since onComplete
may be executed within a different actor context that can point to a different sender resulting in message being sent to a wrong actor.
Upvotes: 1