Играйте в 2.7 фоновые задачи и асинхронные c сервисы - PullRequest
0 голосов
/ 09 мая 2020

Мне интересно, как правильно работать с asyn c сервисами (возвращает Future [OfResult]) внутри фоновых задач Play akka. В игровых документах нет информации об этом. Кажется, я не могу просто вернуть Future [TaskResult] в конце и выполнить действия реактивным способом, поэтому я использую Await.result для каждого вызова службы asyn c . И даже если я использую свой собственный контекст выполнения, иногда я получаю странные исключения из гладкого слоя db, и задача перестает работать, это совсем не устойчиво (я ожидал, что по крайней мере следующее расписание будет работать), поэтому я думаю, что делаю это неправильно.

Задача простая, у меня есть таблица событий в базе данных с некоторыми полями и диапазоном дат, каждый день я проверяю, находится ли текущая дата внутри диапазона дат, удаляю прошедшие события и активирую новые события. Это требует от меня:

  1. Получить все события - это список Future [Event]
  2. Пролистать список и изменить или удалить события

Я делаю это в процедурном стиле с блокировкой Await.result

При небольшом количестве событий он выходит из строя очень редко, но с тысячами - он выходит из строя довольно скоро (я полагаю, из-за ограниченного пула базы данных?)

Это не похоже на неправильную конфигурацию базы данных, потому что при обычном действии контроллера asyn c все работает нормально с огромным объемом данных, поэтому я полагаю, что делаю это неправильно

1 Ответ

1 голос
/ 11 мая 2020

Никогда не используйте Await.result в логах приложения c, так как это заблокирует вызывающий поток и потенциально приведет к нехватке ресурсов для пула потоков. Дополнительную информацию можно найти в документации Akka здесь: https://doc.akka.io/docs/akka/current/typed/dispatchers.html#blocking -needs-тщательное управление . Возможно, именно поэтому вы видите, что это не удается.

Если будущее зависит от другого, вы должны связать их, используя map или flatMap. Для превращения List[Future[T]] в Future[List[T]] вы можете использовать Future.sequence.

Если то, что вы имеете в виду под «фоновыми задачами акка», использует планировщик ActorSystem , как в этой статье нет необходимости блокировать Runnable, переданный планировщику на время, просто позвольте ему запускать ваши будущие задачи и затем вернуться.

Важно понимать, что будущие операции будут выполняться в одном или нескольких других потоках, поэтому, если вы хотите наблюдать, что он прогрессирует и завершается или терпит неудачу, вам придется добавить это с помощью обратных вызовов для фьючерсов (для пример onComplete о конечном будущем).

...