Nested Future.sequence executes included Futures sequentially - scala

I have a future(doFour) that is executed and results passed to a flatmap.
Inside the flatmap I execute two more future(doOne and doTwo) functions expecting them to run on parallel but I see they are running sequentially (2.13). Scastie
Why are doOne and doTwo not execute in parallel ?
How can I have them to run in parallel ?
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{Await, Future}
object Test {
def doOne(): Future[Unit] = Future {
println("startFirst"); Thread.sleep(3000); println("stopFirst")
}
def doTwo(): Future[Unit] = Future {
println("startSecond"); Thread.sleep(1000); println("stopSecond")
}
def doFour(): Future[Unit] = Future {
println("do 4"); Thread.sleep(1000); println("done 4")
}
def main(args: Array[String]) {
val resOut = doFour().flatMap { a =>
val futureOperations = Seq(doOne(), doTwo())
val res = Future.sequence(futureOperations)
res
}
val stream = Await.result(resOut, Duration.Inf)
}
}

A Future becomes eligible for execution as soon as it is created. So this line creates two Futures that can potentially be executed:
val futureOperations = Seq(doOne(), doTwo())
The call to Future.sequence will create a new Future that waits for each of the futures to complete in turn, but they will both already be available for execution by this point in the code.
val res = Future.sequence(futureOperations)
If you want Futures to start sequentially you need to use map/flatMap:
val res = doOne().map( _ => doTwo())
With this code doTwo will not be called until doOne completes (and not at all if doOne fails)
The reason that this does not appear to happen in your example is that you are calling a blocking operation in your Future which is blocking a thread that would otherwise be used to execute other Futures. So although there are two Futures available for execution, only one is actually being executed at a time.
If you mark the code as blocking it works correctly:
import scala.concurrent.blocking
def doOne(): Future[Unit] = Future {
blocking{println("startFirst"); Thread.sleep(3000); println("stop First")}
}
def doTwo(): Future[Unit] = Future {
blocking{println("startSecond"); Thread.sleep(1000); println("stop Second")}
}
See the comments section for details of why the default behaviour is different on different versions, and why you should never make assumptions about the relative execution order of independent Futures.

Related

Twitter Futures - how are unused futures handled?

So I have a api in Scala that uses twitter.util.Future.
In my case, I want to create 2 futures, one of which is dependent on the result of the other and return the first future:
def apiFunc(): Future[Response]={
val future1 = getFuture1()
val future2 = future1 map {
resp => processFuture1Resp(resp)
}
future1
}
So in this case, future2 is never consumed and the api returns the result of future1 before future2 is completed.
My question is - will future2 run even though the api has returned?
Further, future1 should not be affected by future2. That is, the processing time for future2 should not be seen by any client that calls apiFunc(). You can think of processFuture1Resp as sending the results of getFuture1() to another service but the client calling apiFunc() doesn't care about that portion and only wants future1 as quickly as possible
My understanding is that futures spawn threads, but I am unsure if that thread will be terminated after the return of the main thread.
I guess a different way to ask this is - Will a twitter.util.future always be executed? Is there a way to fire and forget a twitter.util.future?
If you want to chain two futures where one of them processes the result of the other (and return a future), you can use a for comprehension:
def getFuture1() = {
println("Getting future 1...")
Thread.sleep(1000)
Future.successful("42")
}
def processFuture1Resp(resp: String) = {
println(s"Result of future 1 is: ${resp}")
"END"
}
def apiFunc(): Future[String]={
for {
res1 <- getFuture1()
res2 <- Future(processFuture1Resp(res1))
} yield res2
}
def main(args: Array[String]) {
val finalResultOfFutures: Future[String] = apiFunc()
finalResultOfFutures
Thread.sleep(500)
}
This will print:
Getting future 1...
Result of future 1 is: 42
The value finalResultOfFutures will contain the result of chaining both futures, and you'll be sure that the first future is executed before the second one. If you don't wait for the execution of finalResultOfFutures on the main thread (commenting the last sleep function of the main thread), you will only see:
Getting future 1...
The main thread will finish before the second future has time to print anything.
Another (better) way to wait for the execution of the future would be something like this:
val maxWaitTime: FiniteDuration = Duration(5, TimeUnit.SECONDS)
Await.result(finalResultOfFutures, maxWaitTime)
Await.result will block the main thread and waits a defined duration for the result of the given Future. If it is not ready or completes with a failure, Await.result will throw an exception.
EDITED
Another option is to use Monix Tasks This library allows you wrap actions (such as Futures) and have a greater control on how and when the Futures are executed. Since a Future may start its execution right after its declaration, these functionalities can be quite handy. Example:
import monix.execution.Scheduler.Implicits.global
import scala.concurrent.duration._
def getFuture1() = {
println("Getting future 1...")
Thread.sleep(3000)
println("Future 1 finished")
Future.successful("42")
}
def processFuture1Resp(resp: Task[String]) = {
val resp1 = resp.runSyncUnsafe(2.seconds)
println(s"Future2: Result of future 1 is: ${resp1}")
}
def main(args: Array[String]) {
// Get a Task from future 1. A Task does not start its execution until "run" is called
val future1: Task[String] = Task.fromFuture(getFuture1())
// Here we can create the Future 2 that depends on Future 1 and execute it async. It will finish even though the main method ends.
val future2 = Task(processFuture1Resp(future1)).runAsyncAndForget
// Now the future 1 starts to be calculated. Yo can runAsyncAndForget here or return just the task so that the client
// can execute it later on
future1.runAsyncAndForget
}
This will print:
Getting future 1...
Future 1 finished
Future2: Result of future 1 is: 42
Process finished with exit code 0

Failed to call Future#onSuccess [duplicate]

Just trying to get my first futures use up and running and doing a test similar to an example outlined in the Akka in Action MEAP book. I want to call a web service and return the result in a future. I am using scalaxb to access the web service. I have outlined the code below but when I run it the app terminates without waiting for the response from the service. Maybe someone can tell me what I am missing?
import scala.util._
import control.NonFatal
import scala.concurrent._
import ExecutionContext.Implicits.global
object Test {
val service = (new MyServiceBindings with scalaxb.Soap11Clients with scalaxb.DispatchHttpClients {}).service
def test = {
val f = future {
service.someCall() match {
case Right(resp) => resp
case Left(fault) => throw new Exception("Fault: " + fault)}
}
}
f.onComplete {
case Success(resp) => println("Resp: " + resp)
case Failure(NonFatal(e)) => println("Fail: " + e)
}
}
def main(args: Array[String]): Unit = {
test
}
}
It terminates because the main thread that is executed inside your Test has completed. The threads that are used internally by the Dispatch library don't keep the program from exiting.
You would need to wait on the future since this is the only thing your test app is doing. Put this after the onComplete statement.
import scala.concurrent.duration._
Await.ready(f, 10.seconds)
Now bear in mind that this is bad practice usually. You need it here because your test app is doing nothing else, but in a real app, you wouldn't want to block after each futures call, as that would negate the point of using futures.
You can patch this in the main funtion by adding the following logic to your test application:
def main(args: Array[String]) : Unit = {
// Assuming test is a future that did not complete yet.
while(!test.isCompleted) {
Thread.sleep(100)
}
// Software exits here only after future is completed.
}
Or Better if you have many futures you can implement it this way:
// Assuming you have --> listOfFutures = ArrayBuffer[Future]
def main(args: Array[String]) : Unit = {
while(!listOfFutures.isEmpty) {
listOfFutures.foreach {
future =>
if(future.isCompleted) {
listOfFutures -= future
}
}
//checks which futures are completed every half-a-second
Thread.sleep(500)
}
// Program exits after all futures have been completed.
}

Scala future app terminates before complete

Just trying to get my first futures use up and running and doing a test similar to an example outlined in the Akka in Action MEAP book. I want to call a web service and return the result in a future. I am using scalaxb to access the web service. I have outlined the code below but when I run it the app terminates without waiting for the response from the service. Maybe someone can tell me what I am missing?
import scala.util._
import control.NonFatal
import scala.concurrent._
import ExecutionContext.Implicits.global
object Test {
val service = (new MyServiceBindings with scalaxb.Soap11Clients with scalaxb.DispatchHttpClients {}).service
def test = {
val f = future {
service.someCall() match {
case Right(resp) => resp
case Left(fault) => throw new Exception("Fault: " + fault)}
}
}
f.onComplete {
case Success(resp) => println("Resp: " + resp)
case Failure(NonFatal(e)) => println("Fail: " + e)
}
}
def main(args: Array[String]): Unit = {
test
}
}
It terminates because the main thread that is executed inside your Test has completed. The threads that are used internally by the Dispatch library don't keep the program from exiting.
You would need to wait on the future since this is the only thing your test app is doing. Put this after the onComplete statement.
import scala.concurrent.duration._
Await.ready(f, 10.seconds)
Now bear in mind that this is bad practice usually. You need it here because your test app is doing nothing else, but in a real app, you wouldn't want to block after each futures call, as that would negate the point of using futures.
You can patch this in the main funtion by adding the following logic to your test application:
def main(args: Array[String]) : Unit = {
// Assuming test is a future that did not complete yet.
while(!test.isCompleted) {
Thread.sleep(100)
}
// Software exits here only after future is completed.
}
Or Better if you have many futures you can implement it this way:
// Assuming you have --> listOfFutures = ArrayBuffer[Future]
def main(args: Array[String]) : Unit = {
while(!listOfFutures.isEmpty) {
listOfFutures.foreach {
future =>
if(future.isCompleted) {
listOfFutures -= future
}
}
//checks which futures are completed every half-a-second
Thread.sleep(500)
}
// Program exits after all futures have been completed.
}

In twitter future, how to set function of asynchronize return directly

I am new to future modern, what I expect from the following code is :
launch future task finished!
end of task
but actualy, the "end of task" appear first.
I want the process in function long_task to run asynchronizely.
what did I missed?
import com.twitter.util.Future
object FutureTest extends App{
def long_task(): Future[_] = { //the function of asynchronize processing
Thread.sleep(5000)
println("end of task")
Future.value("")
}
val f = long_task()
println("launch future task finished!")
}
The problem you are encountering is that long_task is a synchronous function that returns a completed future after it has done all the work. A future in and of itself does not start asynchronous work, but is just a handle for notification of asynchronous. It's still up to you to start the work asynchronously.
For your example using a FutureTask with a java ExecutorService will do the trick:
object FutureTest extends App{
val pool: ExecutorService = Executors.newFixedThreadPool(10)
def long_task(): Future[Unit] = {
// create a FutureTask, which is a Callable wrapped by a Future
val f = new FutureTask[Unit](new Callable[Unit]() {
def call(): Unit = {
Thread.sleep(5000)
println("end of task")
}})
// execute the callable
pool.execute(f)
// return the uncompleted future
f
}
val f = long_task()
println("launch future task finished!")
}
If you can use the scala Future instead of Twitter's the syntax gets a little simpler, since they've abstracted the underlying Threadpool work a bit further:
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.{Await, future}
import scala.concurrent.duration._
object FutureTest extends App {
def long_task() = future {
Thread.sleep(5000)
println("end of task")
}
val f = long_task()
println("launch future task finished!")
Await.result(f,10.seconds)
}
Note the Await at the end, which is needed here because with scala's default executorservice, the future work is a daemon thread which will not keep the runtime from quiting as soon as it reaches the last line. Await forces the program to block until the future completes.
Try it this way (create the Future first and execute):
import com.twitter.util.{Future, FutureTask}
object FutureTest extends App{
def long_task(): Future[_] = new FutureTask { //the function of asynchronize processing
Thread.sleep(5000)
println("end of task")
""
}
val f = long_task()
println("launch future task finished!")
}

Scala Futures - built in timeout?

there is an aspect of futures that I do not exactly understand from the official tutorial ref. http://docs.scala-lang.org/overviews/core/futures.html
Do futures in scala have a built in time-out mechanism of some kind? Let's say the example below was a 5 gigabyte text file... does the implied scope of "Implicits.global" eventually cause onFailure to fire in a non-blocking way or can that be defined? And without a default time-out of some kind, wouldn't that imply it's possible neither success nor failure would ever fire?
import scala.concurrent._
import ExecutionContext.Implicits.global
val firstOccurence: Future[Int] = future {
val source = scala.io.Source.fromFile("myText.txt")
source.toSeq.indexOfSlice("myKeyword")
}
firstOccurence onSuccess {
case idx => println("The keyword first appears at position: " + idx)
}
firstOccurence onFailure {
case t => println("Could not process file: " + t.getMessage)
}
You only get timeout behavior when you use blocking to get the results of the Future. If you want to use the non-blocking callbacks onComplete, onSuccess or onFailure, then you would have to roll your own timeout handling. Akka has built in timeout handling for request/response (?) messaging between actors, but not sure if you want to start using Akka. FWIW, in Akka, for timeout handling, they compose two Futures together via Future.firstCompletedOf, one which represents the actual async task and one that represents the timeout. If the timeout timer (via a HashedWheelTimer) pops first, you get a failure on the async callback.
A very simplified example of rolling your own might go something like this. First, an object for scheduling timeouts:
import org.jboss.netty.util.{HashedWheelTimer, TimerTask, Timeout}
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import scala.concurrent.Promise
import java.util.concurrent.TimeoutException
object TimeoutScheduler{
val timer = new HashedWheelTimer(10, TimeUnit.MILLISECONDS)
def scheduleTimeout(promise:Promise[_], after:Duration) = {
timer.newTimeout(new TimerTask{
def run(timeout:Timeout){
promise.failure(new TimeoutException("Operation timed out after " + after.toMillis + " millis"))
}
}, after.toNanos, TimeUnit.NANOSECONDS)
}
}
Then a function to take a Future and add timeout behavior to it:
import scala.concurrent.{Future, ExecutionContext, Promise}
import scala.concurrent.duration.Duration
def withTimeout[T](fut:Future[T])(implicit ec:ExecutionContext, after:Duration) = {
val prom = Promise[T]()
val timeout = TimeoutScheduler.scheduleTimeout(prom, after)
val combinedFut = Future.firstCompletedOf(List(fut, prom.future))
fut onComplete{case result => timeout.cancel()}
combinedFut
}
Note that the HashedWheelTimer I am using here is from Netty.
All of these answers require additional dependencies. I decided to write a version using java.util.Timer which is an efficient way to run a function in the future, in this case to trigger a timeout.
Blog post with more details here
Using this with Scala's Promise, we can make a Future with timeout as follows:
package justinhj.concurrency
import java.util.concurrent.TimeoutException
import java.util.{Timer, TimerTask}
import scala.concurrent.duration.FiniteDuration
import scala.concurrent.{ExecutionContext, Future, Promise}
import scala.language.postfixOps
object FutureUtil {
// All Future's that use futureWithTimeout will use the same Timer object
// it is thread safe and scales to thousands of active timers
// The true parameter ensures that timeout timers are daemon threads and do not stop
// the program from shutting down
val timer: Timer = new Timer(true)
/**
* Returns the result of the provided future within the given time or a timeout exception, whichever is first
* This uses Java Timer which runs a single thread to handle all futureWithTimeouts and does not block like a
* Thread.sleep would
* #param future Caller passes a future to execute
* #param timeout Time before we return a Timeout exception instead of future's outcome
* #return Future[T]
*/
def futureWithTimeout[T](future : Future[T], timeout : FiniteDuration)(implicit ec: ExecutionContext): Future[T] = {
// Promise will be fulfilled with either the callers Future or the timer task if it times out
val p = Promise[T]
// and a Timer task to handle timing out
val timerTask = new TimerTask() {
def run() : Unit = {
p.tryFailure(new TimeoutException())
}
}
// Set the timeout to check in the future
timer.schedule(timerTask, timeout.toMillis)
future.map {
a =>
if(p.trySuccess(a)) {
timerTask.cancel()
}
}
.recover {
case e: Exception =>
if(p.tryFailure(e)) {
timerTask.cancel()
}
}
p.future
}
}
I've just created a TimeoutFuture class for a coworker:
TimeoutFuture
package model
import scala.concurrent._
import scala.concurrent.duration._
import play.libs.Akka
import play.api.libs.concurrent.Execution.Implicits._
object TimeoutFuture {
def apply[A](timeout: FiniteDuration)(block: => A): Future[A] = {
val prom = promise[A]
// timeout logic
Akka.system.scheduler.scheduleOnce(timeout) {
prom tryFailure new java.util.concurrent.TimeoutException
}
// business logic
Future {
prom success block
}
prom.future
}
}
Usage
val future = TimeoutFuture(10 seconds) {
// do stuff here
}
future onComplete {
case Success(stuff) => // use "stuff"
case Failure(exception) => // catch exception (either TimeoutException or an exception inside the given block)
}
Notes:
Assumes Play! framework (but it's easy enough to adapt)
Every piece of code runs in the same ExecutionContext which may not be ideal.
Play framework contains Promise.timeout so you can write code like following
private def get(): Future[Option[Boolean]] = {
val timeoutFuture = Promise.timeout(None, Duration("1s"))
val mayBeHaveData = Future{
// do something
Some(true)
}
// if timeout occurred then None will be result of method
Future.firstCompletedOf(List(mayBeHaveData, timeoutFuture))
}
I'm quite surprise this is not standard in Scala. My versions is short and has no dependencies
import scala.concurrent.Future
sealed class TimeoutException extends RuntimeException
object FutureTimeout {
import scala.concurrent.ExecutionContext.Implicits.global
implicit class FutureTimeoutLike[T](f: Future[T]) {
def withTimeout(ms: Long): Future[T] = Future.firstCompletedOf(List(f, Future {
Thread.sleep(ms)
throw new TimeoutException
}))
lazy val withTimeout: Future[T] = withTimeout(2000) // default 2s timeout
}
}
Usage example
import FutureTimeout._
Future { /* do smth */ } withTimeout
If you want the writer (promise holder) to be the one who controls the timeout logic, use akka.pattern.after, in the following way:
val timeout = akka.pattern.after(10 seconds, system.scheduler)(Future.failed(new TimeoutException(s"timed out during...")))
Future.firstCompletedOf(Seq(promiseRef.future, timeout))
This way, if your promise completion logic never takes place, your caller's future will still be completed at some point with a failure.
You can specify the timeout when you wait on the future:
For scala.concurrent.Future, the result method lets you specify a timeout.
For scala.actors.Future, Futures.awaitAll lets you specify a timeout.
I do not think there is a timeout built-in the execution of a Future.
Nobody's mentioned akka-streams, yet. The flows have an easy completionTimeout method, and applying that on a single-source stream works like a Future.
But, akka-streams also does cancellation so it can actually end the source from running, i.e. it signals the timeout to the source.
Monix Task has timeout support
import monix.execution.Scheduler.Implicits.global
import monix.eval._
import scala.concurrent.duration._
import scala.concurrent.TimeoutException
val source = Task("Hello!").delayExecution(10.seconds)
// Triggers error if the source does not complete in 3 seconds after runOnComplete
val timedOut = source.timeout(3.seconds)
timedOut.runOnComplete(r => println(r))
//=> Failure(TimeoutException)
This version works without using any external timer (just Await.result)
import scala.concurrent._
import scala.concurrent.duration.FiniteDuration
object TimeoutFuture {
def apply[A](
timeout: FiniteDuration
)(block: => A)(implicit executor: ExecutionContext): Future[A] =
try {
Future { Await.result(Future { block }, timeout) }
} catch {
case _: TimeoutException => Future.failed(new TimeoutException(s"Timed out after ${timeout.toString}"))
}
}
I'm using this version (based on Play example above) which uses Akka system dispatcher:
object TimeoutFuture {
def apply[A](system: ActorSystem, timeout: FiniteDuration)(block: => A): Future[A] = {
implicit val executionContext = system.dispatcher
val prom = Promise[A]
// timeout logic
system.scheduler.scheduleOnce(timeout) {
prom tryFailure new java.util.concurrent.TimeoutException
}
// business logic
Future {
try {
prom success block
} catch {
case t: Throwable => prom tryFailure t
}
}
prom.future
}
}
The simplest way to specify timeout on Future IMO is scala's built in mechanism using scala.concurrent.Await.ready This will throw a TimeoutException if the Future takes longer than the specified timeout. Otherwise, it will return the Future itself.
Here is a simple contrived example
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration._
val f1: Future[Int] = Future {
Thread.sleep(1100)
5
}
val fDoesntTimeout: Future[Int] = Await.ready(f1, 2000 milliseconds)
val f: Future[Int] = Future {
Thread.sleep(1100)
5
}
val fTimesOut: Future[Int] = Await.ready(f, 100 milliseconds)
You can wait for a future to finish by making use of Await.
import scala.concurrent.duration._
import scala.concurrent.{Await, Future}
val meaningOfLife: Int = Await.result(Future(42), 1.nano)
println (meaningOfLife)
The above prints 42
You may need an implicit ExecutionContext available in which case, just add:
import scala.concurrent.ExecutionContext.Implicits.global
Another way to do it is to use Coeval from monix. This method does not work in all situations, and you can read all about it here.
The basic idea is that sometimes a future does not really take any time and is returning the result of a synchronous function call or value, so this future can be evaluated on the current thread. This is also useful for testing and mocking futures. Also you don't have to specify a timeout which is expected, but still nice to not have to worry about that.
You start by transforming the future into a Task and wrap that task in a Coeval then cross your fingers as you wait to see what you get. This is a very simple example to show how it works:
You need an implicit Scheduler to be able to use it:
import monix.execution.Scheduler.Implicits.global
Coeval(Task.fromFuture(Future (42)).runSyncStep).value() match {
case Right(v) => println(v)
case Left(task) => println("Task did not finish")
}
The above completes and prints 42 to the console.
Coeval(Task.fromFuture(Future {
scala.concurrent.blocking {
42
}
}).runSyncStep).value() match {
case Right(v) => println(v)
case Left(task) => println("Task did not finish")
}
This example prints Task did not finish:
You can simply run the future to completion without giving any timeout interval by setting the timeout to infinite as below:
**import scala.concurrent.duration._
Await.result(run(executionContext), Duration.Inf)**
run function can be as below :
def run(implicit ec: ExecutionContext) = {
val list = Seq(
Future { println("start 1"); Thread.sleep(1000); println("stop 1")},
Future { println("start 2"); Thread.sleep(2000); println("stop 2")},
Future { println("start 3"); Thread.sleep(3000); println("stop 3")},
Future { println("start 4"); Thread.sleep(4000); println("stop 4")},
Future { println("start 5"); Thread.sleep(5000); println("stop 5")}
)
Future.sequence(list)
}