Reputation: 877
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
{
}
}
Upvotes: 1
Views: 78
Reputation: 27595
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))
Upvotes: 3