score:9
As written in the Akka's Future documentation, using Await blocks current thread until awaiting for the result.
Example
import scala.concurrent.Await
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.duration._
implicit val timeout = Timeout(5 seconds)
val future = actor ? msg // enabled by the “ask” import
val result = Await.result(future, timeout.duration).asInstanceOf[String]
This will cause the current thread to block and wait for the Actor to 'complete' the Future with it's reply.
score:0
If you don't want to block on the calling side then don't use Await, use the non blocking callbacks instead like onSuccess, onFailure and onComplete. When you do this, a future task is put into whatever ExecutionContext is in scope at time of ask (?). When a response is received, this callback is invoked asynchronously via the ExecutionContext. This way you avoid blocking all together in the thread that is making the request to the actor and then the callback is handled in the thread pool tied to the ExecutionContext.
In addition, I believe the inbox stuff you mention is geared towards testing out actor stuff in the REPL (at least that's what the docs on ActorDsl) states. Stick with the approach you have of using ask from outside the actor. Let akka create the short lived actor that it needs for the communication under the hood for non-actor to actor calls. Then just switch to a non blocking callback as I suggested above. I believe that's what you are looking for.
score:5
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.
Source: stackoverflow.com
Related Query
- Interact with Akka actor outside actors
- Akkatype with classic actors giving me an error: Unsupported access to ActorContext from outside of Actor
- Akka Logging outside Actor
- Testing Akka actors that mixin Stash with TestActorRef
- How to select akka actor with actorSelection?
- Akka actors unit testing with Scala
- Error message with Scala AKKA Actor
- Akka Actor Test: Automatic reply with a TestProbe
- Akka Actor "ask" and "Await" with TimeoutException
- Is the Akka Actors library installed with the Scala IDE for Scala 2.10?
- The actor pattern with Akka and long running processes
- Failing a scalatest when akka actor throws exception outside of the test thread
- Akka actor forward message with continuation
- Using @Transactional on actors class definition with Akka 2.X.X?
- Akka FSM Actor with stashing and unstashing
- Using OpenGL with Akka Actors: guaranteeing a single thread is used for a specific actor
- Porting simple Scala remote actor example to Akka actors
- Akka actor system with HTTP interface
- How to visualize Actor message flow with Akka 2.1.2?
- Scala Akka actors - getting the state of an actor
- Akka - worse performance with more actors
- How to create akka actor with different path?
- Handling multiple TCP connections with Akka Actors
- Akka actor work handoff with Futures
- Akka http request is not consumed with runFold when it's piped to actor
- Changing Akka actor state by passing a method with arguments to "become"
- Scala and Akka - Testing actors as a system with Akka Testkit
- Exception handling with Akka actors
- Akka actors + Play! 2.0 Scala Edition best practices for spawning and bundling actor instances
- How can I resolve conflicting actor systems while testing akka-http and akka actors at the same spec file?
More Query from same tag
- If scala advocate immutability why it adopted actor model with its mutable nature?
- What is point of /: function?
- Are 2FA TOTP scratch or recovery codes order-sensitive?
- Are there specific rules or precendence while using '+=' to insert data into a Map in Scala?
- Require Function Parameters Implement Method - Scala
- Scala Play 2.5 Controller class to serve static HTML
- Parsing stream of JSON with Argonaut
- Convert Arrays into Spark DataSet in Scala
- Reading comma separated text file in spark 1.6
- Restart ReduceByKeyAndWindows
- scala treeset fails to remove element
- how can i find a key in a map based on a pattern matching in scala
- Replace Values in dataframe conditionally when key appears in a map
- asInstance[T] but with Option[T] as result
- Reading files from Azure Blob Storage by partition
- ConfiguredJsonCodec for snake case ADT
- Unbounded Queue in Akka Streams
- Returning a non-unit value from a scala while loop
- MongoDB ObjectID as JSON using lift-json
- Serialize/Broadcast large Map in Spark + Scala
- How to use Scala's this typing, abstract types, etc. to implement a Self type?
- How to iterate over a huge amount of records with scala sorm
- Apache spark error: not found: value sqlContext
- Searching all file names recursively in hdfs using Spark
- deploying gwt web application on jetty
- Android: Refreshing view from UI thread
- Akka-Http File Upload sending response before request is completely read
- Tapir - Method too large
- Extract string and integer
- Play Json - custom JsResultException