Created
June 14, 2012 21:15
-
-
Save lgiorda/2933001 to your computer and use it in GitHub Desktop.
Akka Futures, Actors, and timeouts..
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object FuturesTimeoutApp extends App { | |
implicit val timeout = Timeout(10 seconds) | |
val actorSystem = ActorSystem.create("TimeoutActorSystem") | |
val actorA = actorSystem.actorOf(Props[ActorA],"actorA") | |
var responseFuture = actorA ? DoCalculateActorA(6) mapTo manifest[Int] | |
var response = Await.result(responseFuture, 35 seconds) // yes, blocking is bad...bear with us.. | |
println("Response received finally 1:" + response) | |
val responseFuture2 = actorA ? DoCalculateActorA(10) mapTo manifest[Int] | |
val response2 = Await.result(responseFuture2, 60 seconds) | |
println("Response received finally 2:" + response2) | |
} | |
class ActorA extends Actor { | |
implicit val timeout = Timeout(30 seconds) | |
import context.dispatcher | |
def receive = { | |
case DoCalculateActorA(n) => | |
val router = context.actorOf(Props[ActorB].withRouter(RoundRobinRouter(n))) | |
println("Sending futures to ActorB "+n+" times") | |
val futures = for (i <- 1 to n) yield { | |
router ? DoCalculateActorB mapTo manifest[DoneFromActorB] | |
} | |
println("Done sending all futures to Actor B") | |
val returnVal = Future.sequence(futures).map(f => f.foldLeft(0)((r1,r2) => r1 + r2.result)) | |
println("Piping futures back to sender from Actor A") | |
returnVal pipeTo sender | |
} | |
} | |
class ActorB extends Actor { | |
import context.dispatcher | |
def receive = { | |
case DoCalculateActorB => println("Putting actor ("+self.path.name+","+hashCode+") to sleep for 3500ms") | |
val future = Future {Thread.sleep(3500)} | |
Await.result(future, 6 seconds) | |
println("Future in Actor ("+self.path.name+","+hashCode+")is Done. Returning") | |
sender ! DoneFromActorB(4) | |
} | |
} | |
case class DoCalculateActorA(numberOfCalcs:Int) | |
case object DoCalculateActorB | |
case class DoneFromActorB(result:Int) | |
case class CalculatedResult(result:Long) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
lines 46–47 are an anti-pattern: never ever do that! Instead of blocking one thread you simply block two, leading to thread starvation which is the problem in this program. Using Await.result within an actor is in itself something which I cannot find a valid use-case for.