Program not terminating when using Futures
Asked Answered
P

1

5

I'm trying to concurrently run a function on each file in a directory. Sadly whenever I use Futures my program doesn't want to terminate (runs forever). I have tried using Await.result() with the same result :/

When running the code it executes fine, even "finish?" gets printed and then it hangs...

Heres my code. (I'm new to Scala)

val execService = Executors.newFixedThreadPool(3)
implicit val execContext = ExecutionContext.fromExecutorService(execService)

val futures = for (file <- filesList) yield Future {
   println(file)
   // theFunc(file)
}
val seq = Future.sequence(futures)
seq.onComplete {
   case Success(x) => println("finish?")
   case Failure(e) => println(e)
}
Proliferate answered 13/7, 2020 at 21:14 Comment(2)
Try Await.ready(Future.traverse(filesList)(theFunc), Duration.Inf) where theFunc already returns a Future.Denney
Thanks for the reply, sadly I still can't get it to terminate :/Proliferate
I
7

Executors.newFixedThreadPool uses under the hood defaultThreadFactory which creates non-daemon thread

Returns a default thread factory used to create new threads. This factory creates all new threads used by an Executor in the same ThreadGroup... Each new thread is created as a non-daemon thread

Because these are non-daemon threads the program does not terminate. On the other hand, for example, scala.concurrent.ExecutionContext.Implicits.global creates daemon threads

val threadFactory = new DefaultThreadFactory(daemonic = true,
                                             maxBlockers = getInt("scala.concurrent.context.maxExtraThreads", "256"),
                                             prefix = "scala-execution-context-global",
                                             uncaught = (thread: Thread, cause: Throwable) => reporter(cause))

where we note daemonic = true, so the following program would terminate at the end

implicit val execContext = scala.concurrent.ExecutionContext.Implicits.global

val futures = for (file <- filesList) yield Future {
   println(file)
   // theFunc(file)
}
...

Based on

Iyre answered 13/7, 2020 at 21:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.