fogbow / src / main / scala / fogbow / example / actor / ShowTheFuture.scala

package fogbow.example.actor

import akka.actor.{Actor, ActorRef, PoisonPill}
import Actor._
import akka.dispatch.Future

import scala.util.Random

object ShowTheFuture {
  
  var verbose = false

  val randomGen = new Random

  case object Square
  case object AddOne

  class CalculatingActor (val number: Int) extends Actor {

    def receive = {

      case Square =>
	//Thread.sleep(randomGen.nextInt(100))
	Thread.sleep(number)
	val squared = number*number
        if (verbose) println("SQ: " + number + " -> " + squared)
	self reply (squared)

      case AddOne =>
	Thread.sleep(randomGen.nextInt(10))
	val added = number + 1
	if (verbose) println("ADD: " + number + " -> " + added)
	self reply (added)
    }

  }

  def main (args: Array[String]) {

    if (args.length > 0 && args(0) == "v") 
      verbose = true
  
    // Actor based futures
    val calculators: List[ActorRef] = 
      (1 to 10).toList.map(number => actorOf(new CalculatingActor(number)).start)

    val futureSquareSum: Future[Int] = 
      Future.traverse(calculators)(calc => (calc ? Square).mapTo[Int]).map(_.sum)

    // Retrieve right away: causes blocking
    //val squareSum = futureSquareSum.get

    val futureAddSum: Future[Int] = 
      Future.traverse(calculators)(calc => (calc ? AddOne).mapTo[Int]).map(_.sum)

    // Retrieve after add one messages have been sent: non-blocking
    val squareSum = futureSquareSum.get

    val addSum = futureAddSum.get
    println("\nResult: " + addSum  + " / " + squareSum + " = " + addSum.toDouble/squareSum)

    // Kill the calculators
    calculators.foreach(_ ! PoisonPill)
  }

}

object FutureDemo {

  def main (args: Array[String]) = {

    // Basic futures
    val futureA = Future(42)
    val futureB = Future(10.0)
    println(futureA)
    println("A/B = " + futureA.get / futureB.get)

    // List of futures
    val manyFutures: List[Future[Int]] = 
      (1 to 100).toList.map(x => Future(x * 2 - 1))

    val manyInts: List[Int] = 
      manyFutures.map(futureInt => futureInt.get)

    println("Sum: " + manyInts.sum)

    // Another way that doesn't create Future[Int]'s, but directly
    // constructs a Future[List[Int]]
    val futureIntList: Future[List[Int]] = 
      Future.traverse((1 to 100).toList)(x => Future(x * 2 - 1))

    val traversalSum = futureIntList.map(_.sum).get

    println("Traversal sum: "+ traversalSum)
  }

}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.