Skip to content

Instantly share code, notes, and snippets.

@Krasnyanskiy
Last active July 16, 2016 15:48
Show Gist options
  • Save Krasnyanskiy/7938a44dd23fd7dc0377b6cc60391a87 to your computer and use it in GitHub Desktop.
Save Krasnyanskiy/7938a44dd23fd7dc0377b6cc60391a87 to your computer and use it in GitHub Desktop.
-scala: combine futures
import java.lang.System.currentTimeMillis
import java.util.concurrent.TimeUnit.{MILLISECONDS, SECONDS}
import java.util.concurrent.{TimeUnit, Executors}
import java.util.concurrent.Executors.newFixedThreadPool
import scala.concurrent.ExecutionContext.fromExecutorService
import scala.concurrent.{Future, ExecutionContext}
import scala.util.{Failure, Success}
/**
* @author Alexander Krasniansky
*/
object FutureApp extends App {
val executor = newFixedThreadPool(8)
implicit val executionContext = fromExecutorService(executor)
val start = currentTimeMillis()
val f0: Future[Int] = Future { Thread.sleep(2700); 0 }
val f1: Future[Int] = Future { Thread.sleep(5500); 1 }
val f2: Future[Int] = Future { Thread.sleep(1500); 2 }
val seq: Future[List[Int]] = Future.sequence(f0 :: f1 :: f2 :: Nil)
seq onComplete {
case Success(res) => println { "R:" + res }
case Failure(t) => println { "R:" + t.getMessage }
}
if (!executionContext.awaitTermination(5500, MILLISECONDS)) {
val end = currentTimeMillis()
println { s"executionTime=${(end - start).toDouble / 1000}" }
executionContext.shutdownNow()
}
}
@Krasnyanskiy
Copy link
Author

Krasnyanskiy commented Jul 16, 2016

It's much better to shut down executor within onComplete callback

object FutureApp extends App {
  implicit val executionContext = fromExecutorService(newFixedThreadPool(8))

  lazy val f0: Future[Int] = Future { Thread.sleep(2700); 0 }
  lazy val f1: Future[Int] = Future { Thread.sleep(6500); 1 }
  lazy val f2: Future[Int] = Future { Thread.sleep(1500); 2 }

  Future sequence f0 :: f1 :: f2 :: Nil onComplete {
    case Success(res) =>
      println("R:" + res)
      executionContext.shutdownNow()
  }

}

@Krasnyanskiy
Copy link
Author

Krasnyanskiy commented Jul 16, 2016

object FutureApp extends App {
  implicit val executionContext = fromExecutorService(newFixedThreadPool(8))

  /*lazy*/ val f0: Future[Int] = Future { Thread.sleep(2700); 0 }
  lazy val f1: Future[Int] = Future { Thread.sleep(6500); 1 }
  lazy val f2: Future[Int] = Future { Thread.sleep(1500); 2 }

  Thread.sleep(8000)

  if (f0.isCompleted) {
    // test laziness
    println("Ready")
  }

  Future sequence f0 :: f1 :: f2 :: Nil onComplete {
    case Success(res) =>
      println("R:" + res)
      executionContext.shutdownNow()
  }

}

or

lazy val list =
    Future { Thread.sleep(2700); 0 } ::
    Future { Thread.sleep(6500); 1 } ::
    Future { Thread.sleep(1500); 2 } :: Nil

Future sequence list onComplete {
  case Success(res) =>
    println("R:" + res)
    executionContext.shutdownNow()
}

or

lazy val seq = for (idx <- 0 until 5) yield Future {
  Thread.sleep(Random.nextInt(5000)); idx
}

Future sequence seq onComplete {
  case Success(res) =>
    println("R:" + res)
    executionContext.shutdownNow()
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment