Reputation: 487
I’m wondering what is the correct way to work with async services (returns Future[OfResult]) inside Play background akka tasks. There is no information about it in play docs, It seems I can’t just return Future[TaskResult] at the end and get things done in a reactive way, so I’m using Await.result for each async service call. And even if I use my own custom execution context, sometimes I get weird exceptions from slick db layer and task stops working, this is not resilient at all (I would expect at least next schedule to work) so I think I’m doing it wrong.
The task is simple, I have an events table in database with some fields and date range, each day I’m checking if current date is inside date range, I remove passed events and activate new events. It requires me to:
I’m doing it in procedural style with blocking Await.result
With small events count it fails very rare but with like thousands - it fails pretty soon (I assume because of limited database pool?)
It doesn’t look like just wrong database configuration because in regular async controller action everything works fine with huge amount of data so I suppose I’m doing it wrong
Upvotes: 0
Views: 41
Reputation: 11479
You should never use Await.result
in application logic as it will block the calling thread and potentially starve your threadpool. See more in the Akka docs here: https://doc.akka.io/docs/akka/current/typed/dispatchers.html#blocking-needs-careful-management . This could be why you are seeing it failing.
If a future depends on another you should chain them using map
or flatMap
. For turning a List[Future[T]]
into a Future[List[T]]
you can use Future.sequence
.
If what you mean with "background akka tasks" is using the scheduler of the ActorSystem
like in this article there is no need for the operation to block the Runnable
passed to the scheduler for the duration, just let it trigger your future tasks and then return.
It is important to understand that the future operations will execute on one or more other threads, so if you want to observe that it progresses and completes or fails you will have to add that with callbacks on the futures (for example onComplete
on the final future).
Upvotes: 1