1

I have a scenario where the program ends before the future call executes when i warp the call to calltoFutureMethod(data) method in map.

So i had replaced it with Await.result but i do not want to use Await as it blocks but can not also do:

calltoFutureMethod(data) map{
result => sendData(newData)
}

as tail recursion does not allow it. Is there any other way without Await and Thred.sleep with tail recursion?

   @scala.annotation.tailrec
      def sendData(
      data: List[String]
      ): Unit =
    data match {
    case head::tail =>
         val result = for {
         p <- calltoFutureMethod(data)
         } yield p
         val putDataList = Await.result(result, 10.seconds)
         sendData(newData)
         }
    case Nil => ...
    }

    def callToFutureMethod(data: List[String]) =
    {
    Future
     {
     }
    }
Avenger
  • 793
  • 11
  • 31

1 Answers1

3

You don't need to use tail recursion if you map/flatMap on Future/IO/Task or any other structure which implements trampoline to be stack safe. So:

calltoFutureMethod(data) map {
  result => sendData(newData)
}

IS safe.

The fact that your program terminates is probably because the ExecutionContext you use is a daemon (e.g. ExecutionContext.Implicits.global) - JVM is allowed to terminate if all remaining threads are daemons, so either wait for the end of the future in your main function, or define/use ExecutionContext that is NOT a deamon, at least for these futures.

import java.util.concurrent.Executors

import scala.concurrent.ExecutionContext

// pick up whatever Executor you need
implicit val customExecutionContext: ExecutionContext =
  ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))
Mateusz Kubuszok
  • 24,995
  • 4
  • 42
  • 64
  • Well it worked. Thanks but now even the future gets complete, it keeps the program alive. Is there any way to shut the application once everything is done? – Avenger Apr 02 '20 at 09:53
  • Yes, once you end your program and you know it should end for sure - terminate the `Executor` manually via `executor.shutdown()` (for that you need to save the reference to `Executor` before you pass it into `ExecutionContext`). – Mateusz Kubuszok Apr 02 '20 at 10:17