ねぎ嫌い

思いついたことをてきとうに。

GoogleApisライブラリに実装されているExponential Backoff

動機

Google Admin SDKを使って遊んでる時にふと気になって読んだので残しておく。
調査の経過はZennのScrapにしてある。

GoogleApisライブラリのExponential Backoffを追いたい

結論

googleapisが依存しているgaxios(Axiosのラッパー)の中で実装されている。
retry.tsでリトライに関する判定等を行なっており、内部で再施行回数によって指数的に待ち時間を挿入している。
実際にbackoffを計算しているところを抜粋すると以下

  // Formula: retryDelay + ((2^c - 1 / 2) * 1000)
  const delay =
    retryDelay + ((Math.pow(2, config.currentRetryAttempt) - 1) / 2) * 1000;

ref. https://github.com/googleapis/gaxios/blob/v6.5.0/src/retry.ts#L67-L69

Exponential Backoffの実装で見かける(気がする)Jitterに関しては考慮されていなかった。

詳細

googleapisライブラリから実際にリクエストを投げるまでの流れは以下のライブラリを経由して実行されている。
googleapis > googleapis-common > google-auth-library > gaxios

googleapis

googleapisが担っている部分はI/Fの提供と後続のAdapter/Bridge的な役割に見える。
実際 Admin APIの中身を見ていると処理の大半がprotobufから生成したと思われるI/Fの定義とちょっとしたブリッジのためのコードしかない。
処理の実態は createApiRequest なる関数で行っていることがわかる。
createApiRequest 自体は googleapis-common で実装されている。

googleapis-common

googleapis-commonが担っているのは認証とAPIコールの橋渡しに見える。
上述した createApiRequest の実体を読んでいると、認証を要求したり、認証と一体化してるgoogle-auth-libraryを呼び出している。

google-auth-library

ここでは認証情報が付与されていなかったらOAuthなりService Accountなり経由でトークンを発行し、そのトークンを用いてGaxios経由でAPIコールするようなミドルウェアに見える。
例えばここら辺を見ると、一度APIコールして認証系のエラーが出たらリフレッシュトークンを再取得して再実行するような作りをしている。
ここらへんを眺めてるとどういう認証方式があるのか、それぞれでどう動いているのかがコードベースでわかるので認証で詰まったら読んでおきたい。

gaxios

前述の通り、AxiosのラッパーでありHTTPリクエスト・レスポンス周りに対して責務を持っているように見える。
multipartなリクエストを投げる時にGeneratorを使ってたりするのでどっかでちゃんと理解したい。

おわり

たまにしか読まないけどライブラリを読むのも勉強になっていいね。