← 「自動でつぶやく機械を作った」のに、走り出す前に止まってくれた話 "迷子のdurable-cronが9c351486を発射していた話" →
第51話

第051話 「毎日正午の再試行を予約した」ら、その予約が自分で自分を消せずに残り続けていた話

いつ困る?

「終わったら自分で片付ける」仕組みって、便利そうに見えますよね。使い捨ての予約が終わったら自分で予約を解除する——余計なものを残さない、一見完璧な設計です。

でもこの「自分で片付ける」、コードの置き場所を間違えると一度も実行されないという落とし穴があります。しかも、暴発しないぶん静かで、何週間も気付けない。

何が起こったか

自動購入の試験を走らせるうちに、前日の失敗を翌日の正午に再試行する仕組みが必要になりました。「明日の正午に再試行、明後日も、ずっと」——成功するまで、あるいは期限が来るまで毎日試す、という要件です。

ところが調べてみると、以前に使った使い捨てスクリプトの「自分で予約を消す」処理が、一度も動いたことがないことが分かりました。原因は直球すぎるほど直球で、スクリプトの途中に「ここで終了」という行が書いてあり、その後ろに片付け処理が置かれていたのです。終了行に到達した瞬間に処理は終わるので、後ろに何を書いても永遠に実行されない。消し忘れた予約が、日付指定つきの残骸として crontab に残り続けていました。

さらにその日はもう一つ学びがありました。正午の販売に間に合わせるための再試行設計が「失敗したら2分、4分、8分と間隔を空けて3回」という作りだったのですが、打ち切る時刻を計算してみると販売開始の2分前にリトライが終わる。待ち構えているはずの再試行が、肝心の瞬間より先に帰宅する設計だったのです。

何が変わったか

2つ直しました。

教訓は2つ。「終わったら片付ける、はコードのどこに置くかで永遠に実行されない」と、「再試行設計は、いつ諦めるかより先に、いつまで粘るかを決める」。どちらも地味ですが、動くものを“回し続ける”段階でしか顔を出さない種類のバグです。

<details><summary>▶ 技術的にどうなってるか</summary>

</details>