У меня есть приложение Scala, которое использует несколько источников данных и объединяет объединенный вывод, приложение вызывает несколько HTTP-вызовов параллельно и ожидает их результатов, когда все они разрешены, оно объединяет их вывод в один объект результата и отправляет ответназад как будущее Scala.Код:
val providers = getProviders()
val futures = for (p <- providers) yield searchSource(p, req)
val result = waitAll(futures)
val emptyList = Option(ProductList(Vector.empty, ListSummary(0, 0, 0)))
result.map { x =>
x.foldLeft(emptyList)((r, c) => {
if (c.isSuccess) ProductList.merge(r, c.get) else r
})
}
Сначала он получает список строк провайдеров, затем запускает параллельные вызовы для каждого из них в searchSource.
Функция searchSource сама возвращает Future[Option[ProductList]]
Метод ожидает завершения всех фьючерсов, для чего он вызывает функцию waitAll:
protected def waitAll[T](futures: Seq[Future[T]])(implicit ec: CustomExecutionContext): Future[Seq[Try[T]]] =
Future.sequence(lift(futures))
protected def lift[T](futures: Seq[Future[T]])(implicit ec: CustomExecutionContext): Seq[Future[Try[T]]] =
futures.map(_.map { Success(_) }.recover { case t => Failure(t) })
После ожидания завершения всех фьючерсов он объединяет результаты в один составной объект и возвращает его как будущее.,Для этого я использую функцию foldLeft.
Существуют ли какие-либо "официальные" монадические / идиоматические способы решения проблемы этого типа или есть примеры, оптимизированные для производительности, для этого типа сценария использования?