The Await.receive
is part of the Scala concurrency API and has nothing to do with actors. Its purpose is the block the current thread until the provided future completes, or the timeout limit kicks in and the whole thing ends in a timeout exception.
The ask operator ?
will indeed create a temporary actor with the sole purpose of awaiting for the reply from the actor pointed to by the aref
variable and completing the future you got when you called the ask operator with the received reply.
So your code is essentially blocking the entire thread. As it was indicated, if you want to free up the current thread and continue doing some other work you can attach a callback to the future.
implicit val ctx: ExecutionContext = //provide execution context here
implicit val timeout: Timeout = // provide timeout here
aref ? GroupReceive(fromRank)) onSuccess { res =>
//do something with res here, asynchronously
}
// some other code which runs without being blocked...
The above code can be rewritten with the actor DSL you mentioned above:
import akka.actor.ActorDSL._
implicit val actorSystem: ActorSystem = // provide an actor system here or any actor ref factory
actor(new Act {
aref ! GroupReceive(fromRank)
context.setReceiveTimeout(timeout) //optional
become {
case ReceiveTimeout => {
//handle the timeout
context.stop(self)
}
case res => {
//do your thing with res, asynchronously
context.stop(self)
}
}
}
//some other code which won't wait for the above operations
The latter version also creates a new temporary actor which sends the GroupReceive
message and then waits for a reply, after which it kills itself.
The bottom line is that in order to receive a message from an actor you must be an actor yourself. Actors can't just send message to something other than an ActorRef
.
So either you use the ask pattern which creates a temporary actor behind the scenes and manages this temporary actor's lifecycle itself, exposing to you just a nice simple future to work with, or you can create the temporary actor yourself, but then you have to manage its lifecycle (i.e. remember to kill it once it has done its job)
Choose the option that suits you best.
mapTo[Type]
instead ofasInstanceOf
– SaadasInstanceOf
throws an exception, when it fails.mapTo
returns a failed future. – CapriccioasInstanceOf
might actually succeed and fail later, when a specific method is called. – Capricciosystem.actorOf(...)
– Saadsystem.actorOf(...)
is not the only way to create an actor.ask
or?
creates a new actor,ActorDSL.inbox
creates a new actor. – Gingivitis