自動リトライとは?解説
自動リトライは、失敗した処理を、その失敗が一時的で2回目の試行で成功するという賭けのもとに、自動で再実行します。
リトライは、信頼できないシステムに対処するための最もシンプルで古い手段です。CIでは、あるクラスの失敗を「人が調査して再実行する」から「システムが処理する」へと変えます。しかしリトライが良い考えなのは一時的な失敗に対してのみであり、誤った種類の失敗に適用すると事態を悪化させます。
核となる考え方
処理が失敗すると、自動リトライは単にある上限までもう一度試します。暗黙の前提は、失敗が一時的だったということです。一時的な状態が解消し、同じ入力が今度は成功をもたらすというわけです。真に一時的な失敗に対しては、これは非常に効果的で、余分な時間はわずかしかかかりません。
リトライが役立つ場合
リトライが役立つのは、失敗が環境的で自然に解消する場合です。切断された接続、503を返すregistry、混雑したrunnerでの短時間のメモリ不足などです。処理は有効でした。ただ一瞬、環境が邪魔をしただけです。
リトライが害になる場合
決定論的な失敗をリトライするのは誤りです。失敗するassertion、コンパイルエラー、欠落した環境変数は、どの試行でも同じように失敗するため、リトライは分を浪費し、避けられない赤を遅らせるだけです。冪等でない副作用(半分だけ成功したdeploy)をリトライするのは、積極的に危険ですらあります。
リトライを安全にする
- ハードな失敗が永遠にループしないよう、試行回数に上限を設けます。
- 苦しんでいる上流を叩かないよう、backoff(理想的にはjitter付き)を加えます。
- すべての失敗ではなく、一時的なエラークラスにリトライを限定します。
- 最初の試行が部分的でも安全なよう、リトライする処理が冪等であることを保証します。
Latchkeyの視点
Latchkeyの自己修復managed runnerは、自動リトライを選択的に適用します。ネットワークの瞬断やout-of-memory killといった検出された一時的および機械的な問題で失敗したjobをリトライするため、一度きりの瞬断でbuildが失敗することはなく、一方で決定論的なコードの失敗は本来あるべき通り素早く失敗させます。
重要なポイント
- 自動リトライは、失敗した処理を人なしで再実行します。
- 一時的な失敗には有効で、決定論的な失敗には害になります。
- 試行回数に上限を設け、backoffを加えて上流を叩きすぎないようにします。
- 部分的な副作用を避けるため、冪等な処理だけをリトライします。