Reputation: 20222
I have this code, where I am making an ask request in Scala:
someActorRef ? SomeMessage()
However, I'm getting this message:
could not find implicit value for parameter timeout: akka.util.Timeout
I also tried this:
Await.ready(someActorRef ? SomeMessage(), Duration("3 seconds")).asInstanceOf[String]
But I get the same message.
Anyway, I don't want to block. I want to get a Future
and then later on give it an onComplete
callback.
Can I ask for a message from another actor without blocking?
Upvotes: 2
Views: 2865
Reputation: 14806
You can. But don't use ask
. Just pipe
result to the sender. E.g. let's say this is an actor which performs long running task and returns a future:
class LongRunningTaskPerformer extends Actor {
import context.dispatcher
override def receive: Receive = {
case PerformTask => someLongRunningTask() pipeTo sender()
}
}
class QueryPerformer extends Actor {
val longRunningTaskPerformer = context.actorOf(LongRunningTaskPerformer.props())
override def receive: Receive = {
case TriggerLongRunningTask => longRunningTaskPerformer ! PerformTask
case result @ Result => // do something with your result
}
}
In this case, I'm sending a message PerformTask
to LongRunningTaskPerformer
actor. When the future is being completed, result will be sent to my QueryPerformer
. No blocking. Easy.
Upvotes: 0
Reputation: 9023
ask
needs an implicit Timeout
, after which it will just fail the Future with a TimeoutException
.
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
implicit val timeout = Timeout(5 seconds)
val f = someActorRef ? SomeMessage()
Note that nothing will block for those 5 seconds, the ask
pattern is fully async/non-blocking. It will give you back a Future
, on which you can block (NOT RECOMMENDED) or attach a callback (as you wish)
f.onComplete(doSomething(_))
More info here.
Upvotes: 5