このプロジェクトについて
EDINET(有価証券報告書等)の開示データをもとに、日本株の財務指標・投資判断スコアを日次で算出・公開しているサービスです。
公開サイトはこちら →
https://stocks.happy-life-design.net
前回の記事はこちら →
https://qiita.com/rightcross-ae86/items/ac4e56fb41310807e8f6
今回やったこと
以前、長時間の重い処理を実行中にサーバーの温度が上がりすぎ、強制的に電源が落ちる事態が発生しました。再発を防ぐため、一定の温度に達したら該当する処理を自動で一時停止し、温度が下がったら自動で再開する仕組みを新たに実装しました。ところが、実装の過程でこの仕組み自体に2つの落とし穴が見つかりました。安全装置を作ったつもりが、その安全装置の方にバグが潜んでいた話です。
落とし穴1: 一時停止コマンドがそのままでは動かなかった
対象の処理はコンテナ内で動いているため、コンテナの外から一時停止コマンドを送る必要がありました。最初はコマンドをそのままコンテナ内で実行する形にしていましたが、実行環境に該当コマンドのバイナリが入っておらず、エラーで失敗していました。コマンドをシェル経由で呼び出す形に変更し、解消しました。
落とし穴2: 一時停止対象のプロセスを誤って見失う
一時停止・再開の対象プロセスは、実行中のプロセス一覧を都度スキャンして特定する方式にしていました。ところが、プロセスがfork(複製)する瞬間、一時的に親プロセスと全く同じ情報を持つ子プロセスが存在するタイミングがあり、これを誤って別の対象として検知してしまうことがありました。一度見つけたプロセスの情報を保持しておき、そのプロセスが消えたときだけ再スキャンする方式に変更し、誤検知を解消しました。
次にやること
この2件は実装中の動作確認で発見・解消済みです。ただし同じ実装の中でもう1件、影響がより大きいバグも見つかっています。温度を読み取る処理そのものに関わる不具合で、「安全装置の肝心な機能が実は一度も働いていなかった」という重い内容のため、明日以降に改めて単独の記事として扱う予定です。
まとめ
熱暴走を防ぐための安全装置を作ったところ、装置自体の実装に2つの見落としがありました。緊急時にしか動かない仕組みほど、平常運用のテストだけでは気づけない不具合が潜みやすいという教訓になりました。気になる点・ご質問があればコメントでお知らせください。