retry
Ejecuta de nuevo un efecto inestable hasta que tenga éxito — hasta attempts veces, con backoff opcional entre fallos.
Lección
Los pipelines reales llaman a servicios reales, y los servicios
reales fallan de vez en cuando. La respuesta hecha a mano es un bucle
for con un try/catch, un
contador y un Future.delayed — copiada en cada proyecto,
sutilmente distinta cada vez. retry(attempts, f) es ese
bucle, una sola vez: ejecuta f, y ante un error vuelve a
ejecutarlo, hasta attempts ejecuciones en total; agotado
el presupuesto, el último error se relanza con su stack
trace original. El hook delay recibe el número de fallos
(1, 2, …), así que el backoff es una línea:
delay: (failed) => Duration(seconds: failed).
mapRetry(attempts, f) es la misma idea por elemento: un
map en el que cada llamada tiene
su propio presupuesto de reintentos. Está construido sobre el
mapAsync seguro en paralelo, así que bajo
concurrent(n) cada
elemento en vuelo reintenta de forma independiente — un
elemento lento e inestable se reejecuta mientras sus vecinos avanzan
sin problema, y el orden se sigue preservando. Para reintentar un
pipeline entero, envuelve su terminal:
retry(3, () => fxAsync(…).toList()) — el
resultado parcial se descarta y el pipeline se reejecuta desde un
iterador nuevo.
Extensión de fxdart (sin contraparte en FxTS), inspirada en
retry/retryWhen de Rx — rediseñada para el
modelo pull, donde «resuscribirse» significa «construir el iterable
otra vez». Para un manejo tipado del fallo cuando los
reintentos se agotan, pásale el resultado a
eitherCatching.
Demo 1 · Un fetch inestable, con backoff
Demo 2 · mapRetry bajo concurrent
Pruébalo tú
Ejercicio: haz que la importación sobreviva a sus filas inestables.
timeout — acota cuánto puede tardar cada pull ·
concurrent — los reintentos son independientes por elemento en vuelo ·
errores tipados — cuando el fallo debe ser un valor, no una excepción