Search code examples
multithreadingscalaexecutioncontext

Know when all jobs are completed in ExecutionContext.Implicits.global


I have a simple program to do a blocking IO using futures in ExecutionContext.Implicits.global. I want to bench mark the performance of executing this IO for 100 times, but my loop ends before all the future completes. Is there a way to terminate only when all the tasks pushed to the ExecutionContext completes?


Solution

  • In the absence of any code, I'll provide a simple version but give the caveat that this is an inaccurate way of measuring and not great for things that take a small amount of time. Only really useful if the operation your measuring actually takes a decent amount of time so most of the time is spent in the Future and not in the test code.

    import scala.concurrent._
    import scala.concurrent.duration._
    import ExecutionContext.Implicits.global
    
    val myList = (1 to 10)
    
    val start = System.currentTimeMillis
    
    val seqFutures = for (elem <- myList) yield {
        Future {
          Thread.sleep(5000) // blocking operation
        }
    }
    
    val result = Future.sequence(seqFutures)
    
    Await.result(result, 30.seconds)
    val end = System.currentTimeMillis
    
    println(s"${end-start} seconds")
    

    If you are going to have a large number of blocking IO calls, it can be worth configuring a separate execution context that has a larger thread pool just for the blocking IO to avoid the blocking IO consuming all your threads.