↩️

TypeSciprtで指数バックオフのUtils関数を作ってみた

2025/02/26に公開

指数バックオフは、ネットワーク アプリケーションの標準的なエラー処理方法で、クライアントはリクエスト間の遅延を増加させながら、失敗したリクエストを定期的に再試行します

https://cloud.google.com/memorystore/docs/redis/exponential-backoff?hl=ja

この指数バックオフをよく使うのでUtils関数化してメモ

完成品

const retryWithExponentialBackoff = async (
  callback: Function,
  { maxRetries = 10, maxBackoff = 32000, maxRandomMilliseconds = 1000 } = {}
) => {
  let retries = 0;
  while (true) {
    try {
      return await callback();
    } catch (error) {
      if (retries >= maxRetries) throw error;
      await new Promise((resolve) =>
        setTimeout(
          resolve,
          Math.min(2 ** retries * 1000 + Math.random() * maxRandomMilliseconds, maxBackoff)
        )
      );
      retries++;
    }
  }
};

挙動

受け取ったcallbackでエラーがスローされ続けると以下のような待ち時間を待ってからリトライを繰り返します

試行回数 待ち時間 累計待ち時間
1 1 秒 ~ 2 秒 1 秒 ~ 2 秒
2 2 秒 ~ 3 秒 3 秒 ~ 5 秒
3 4 秒 ~ 5 秒 7 秒 ~ 10 秒
4 8 秒 ~ 9 秒 15 秒 ~ 19 秒
5 16 秒 ~ 17 秒 31 秒 ~ 36 秒
6 32 秒 63 秒 ~ 68 秒
7 32 秒 95 秒 ~ 100 秒
8 32 秒 127 秒 ~ 132 秒
9 32 秒 159 秒 ~ 164 秒
10 エラーを投げる
株式会社find | 落とし物クラウド

Discussion