retry
불안정한 효과를 성공할 때까지 다시 실행합니다 — 최대 attempts번, 실패 사이에 선택적 백오프를 두고서.
강의
실제 파이프라인은 실제 서비스를 호출하고, 실제 서비스는 가끔
실패합니다. 손으로 짠 답은 try/catch와
카운터, Future.delayed를 갖춘 for 루프 —
프로젝트마다 복사되면서 매번 미묘하게 달라지는 코드입니다.
retry(attempts, f)는 그 루프를 한 번으로 정리한
것입니다. f를 실행하고, 에러가 나면 다시 실행하되 총
attempts번까지만 실행합니다. 예산이 다 떨어지면
마지막 에러가 원래 스택 트레이스와 함께 다시 던져집니다.
delay 훅은 실패 횟수(1, 2, …)를 받으므로
백오프는 한 줄이면 됩니다:
delay: (failed) => Duration(seconds: failed).
mapRetry(attempts, f)는 같은 아이디어를 원소 단위로 적용한
것입니다. 모든 호출이 각자의 재시도 예산을 갖는
map입니다. 병렬 안전한
mapAsync 위에 만들어져 있어서
concurrent(n) 아래에서는
진행 중인 각 원소가 독립적으로 재시도합니다 — 느리고
불안정한 항목 하나가 다시 실행되는 동안 이웃들은 그대로 지나가고,
순서는 여전히 보존됩니다. 파이프라인 전체를 재시도하려면 대신
종단을 감싸세요:
retry(3, () => fxAsync(…).toList()) —
부분 결과는 버려지고 파이프라인은 새 이터레이터에서 처음부터 다시
실행됩니다.
Dart 고유의 추가 기능입니다(FxTS에는 대응물이 없습니다). Rx의
retry/retryWhen을 따르되, "재구독"이
"이터러블을 다시 만든다"를 뜻하는 pull 모델에 맞춰 다시
설계했습니다. 재시도가 소진된 뒤의 타입이 있는 실패 처리는
결과를
eitherCatching에
넘기세요.
데모 1 · 불안정한 fetch, 백오프와 함께
데모 2 · concurrent 아래의 mapRetry
직접 해 보기
연습: 불안정한 행이 있어도 임포트가 살아남게 만들어 보세요.
timeout — 각 pull이 걸릴 수 있는 시간에 한도 두기 ·
concurrent — 진행 중인 원소마다 재시도가 독립적으로 유지됨 ·
타입 있는 에러 — 실패가 예외가 아니라 값이어야 할 때