Sondear una API inestable hasta el primer éxito
Requisito
El endpoint de estado de un trabajo de exportación es inestable de
forma determinista: los cuatro primeros sondeos responden
pending y el quinto responde ready. Sondéalo
hasta diez veces, guarda un registro de cada sondeo, detente en el
primer éxito e informa de qué intento ganó, además de cuántos sondeos
se hicieron realmente. Sin aleatoriedad: el número de fallos está
fijado en el código de abajo, así que las dos versiones imprimen lo
mismo en cada ejecución.
La versión con FxDart escribe el reintento como datos:
range(1, 11) es el calendario de sondeos,
map es el transporte, peek anota el registro,
y dropWhile + head son la política de éxito.
Como la cadena es perezosa y se tira de ella valor a valor,
head detiene el sondeo: solo llegan a hacerse cinco
peticiones.
Salida esperada
polling export-2026-07 (up to 10 attempts): poll 1: pending poll 2: pending poll 3: pending poll 4: pending poll 5: ready ready on attempt 5; polls actually made: 5
Lado a lado
Dart nativo
FxDart
Por qué difieren
Con honestidad: el bucle for nativo con un
break es corto, y nadie diría que está mal. La diferencia
está en dónde vive cada pieza. En el bucle, el presupuesto de intentos,
el registro y la prueba de éxito quedan enredados en el flujo de
control: cambia uno y tienes que releer el cuerpo entero. En el
pipeline, cada preocupación es su propio paso con nombre, así que
cambiar la política (primer éxito → tercer éxito, añadir una
transformación, ampliar el presupuesto) significa editar una línea. Y la
garantía de pereza —ningún sondeo después del ganador— es estructural en
FxDart, mientras que en el bucle depende de que el break
esté en el sitio correcto.
Benchmark
Caso async: la escala principal es N = 100,000, no 1,000,000. Cada elemento cuesta una vuelta del event loop en ambos lados, así que un millón de awaits reales mediría el event loop de Dart durante minutos — no el pipeline. Los retardos son de longitud cero y se conserva el límite de concurrencia del ejemplo; lo que comparan las barras es la maquinaria del pipeline.
N = 100
Tiempo Empate
Memoria pico Empate
N = 10,000
Tiempo Gana nativo
Memoria pico Gana FxDart
N = 100,000
Tiempo Gana nativo
Memoria pico Gana FxDart
Las barras son medianas de iteraciones cronometradas repetidas en procesos nuevos por lado (los N pequeños se agrupan por resolución del temporizador). Dos lados a menos del 5% entre sí — o a menos de 0.6 ms, una diferencia que nadie puede percibir — cuentan como empate; las carreras relativas ajustadas se vuelven a medir hasta 5 veces. En una app, cualquier cosa por debajo de unos pocos milisegundos es invisible para el usuario, gane la barra que gane. La memoria es el RSS pico del proceso. La VM de Dart y el dataset son idénticos en ambos lados, así que la diferencia entre las dos barras es lo que retiene el pipeline en sí.