Esperar una secuencia de futuros con tiempo de espera sin fallar en la excepción de tiempo de espera.
Tengo una secuencia de Futures de Scala del mismo tipo.
Después de un tiempo limitado, quiero obtener un resultado para toda la secuencia mientras algunos futures pueden haber tenido éxito, algunos pueden haber fallado y algunos aún no se hayan completado, los futures no completados deben considerarse fallidos.
No quiero usar Await en cada futuro de manera secuencial.
Miré esta pregunta: https://stackoverflow.com/questions/29344430/scala-waiting-for-sequence-of-futures y traté de usar la solución de allí, es decir:
private def lift[T](futures: Seq[Future[T]])(implicit ex: ExecutionContext) =
futures.map(<em>.map { Success(</em>) }.recover { case t => Failure(t) })
def waitAll[T](futures: Seq[Future[T]])(implicit ex: ExecutionContext) =
Future.sequence(lift(futures))
futures: Seq[Future[MyObject]] = ...
val segments = Await.result(waitAll(futures), waitTimeoutMillis millis)
Pero aún obtengo una TimeoutException, supongo que porque algunos de los futures aún no se han completado.
Esa respuesta también afirma:
Ahora Future.sequence (elevado) se completará cuando cada futuro esté completo y representará éxitos y fallas usando Try.
Pero quiero que mi futuro se complete después de que haya pasado el tiempo de espera, no cuando cada futuro de la secuencia se haya completado. ¿Qué más puedo hacer?
davy.ai
Como experto en TI especializado en Scala, puedes usar el método
Future.firstCompletedOf
en conjunto conFuture.sequence
yFuture.failed
para lograr tu objetivo. Aquí te presentamos una manera en la que podrías implementarlo:Puedes usar este método de la siguiente manera:
Esta implementación utiliza una Promesa para crear un nuevo Futuro que tendrá éxito con una secuencia de resultados exitosos, o fallará con una TimeoutException o una RuntimeException que indique que no todos los Futuros se completaron con éxito. Iniciamos un temporizador que completará la Promesa con un fallo si se supera el tiempo de espera, y usamos
Future.firstCompletedOf
para crear un nuevo Futuro que se completará tan pronto como cualquier Futuro de la secuencia se complete, ya sea con éxito o con fallo. Cuando eso sucede, cancelamos el temporizador e inspeccionamos los resultados para determinar si todos los Futuros se completaron con éxito. Si lo hicieron, completamos la Promesa con una secuencia de resultados exitosos. De lo contrario, completamos la Promesa con un fallo que indique que no todos los Futuros se completaron con éxito. Si alguna de los Futuros falla antes de que se acabe el tiempo de espera, cancelamos el temporizador y completamos la Promesa de inmediato con el fallo del primer Futuro fallido.