1.あらすじ
サービス開発をしていた時の話です。新しいSDKの init 部分のコードを書き終わって、何度かデバッグ、テストをしているとローカル環境で立ち上がるサーバーの Port群 が すでに利用されているため使えません、というエラーになりました。
直前までローカル環境使っていたPort群がいきなり占有されるとはおかしいなと思いつつ、その時は、Portを直接 killして解消することにしました。
2. 見逃される疑問
また別の日のことです。同じようにローカル環境を立ち上げると、Portのエラーとなりました。
「ローカル開発環境でしか使われることのないPortが、なぜ占有されているのだろうか」
と不思議に思いました。しかしタスクが色々と積み重なっていること、またチーム内でそういった話が出ていなかったことから、自分のローカルだけの問題だと判断し、原因を探すことは後回しにしてしまいました。
3. 明るみに出たバグ、そして解決
1ヶ月ごろたったある日、チームのSlackでいきなり不具合報告がありました。
「ローカルで立ち上げたNodeJSが SIGTERMで終了していない....(略)」
メッセージを見た瞬間、自分の頭の中で点と点が線になって繋がりました。鼓動が早鐘を打ち、冬なのに背中になんとも言えない気持ち悪さを感じはじめました。
「もしや...」という思いと、「勘違いであってほしい...」という思いを半々で詳細を確認しました。
案の定、原因は私が以前に実装した SDKの初期化コードでした。当時、私はSDKを graceful shutdownするため、globalの SIGTERMを検知し、SDKをcloseする処理を書いていました。
しかしその結果、SIGNALハンドラーを上書きし、本来であればデフォルトで行われる NodeJSサーバーの shutdownが行われていませんでした。
明るみに出るまでに時間がかかったのは、tsxなどTimeoutでのサーバーシャットダウンがあるため、少し時間を放置すると問題がなかったかのように動作します。そのため、短時間で ローカルサーバーの立ち上げを繰り返さないと気が付きづらいためでした。
4. 痛感したこと / 学び
自分の書いたコードでアプリケーション全体に影響を出すような不具合を仕込んでしまったことに、深くショックを受けました。今回はローカル環境のみに影響が出るものでしたが、もし本番環境などにも影響が出るバグを仕込んでいたら、と思うとゾッとします。
そして、冷静にコードを見ると 「SIGNAL ハンドラーを上書き」していることはすぐにわかったのですが、そんなコードを実装した当時の自分の迂闊さを呪いました。
修正プルリクエストを見た時は焦りと後悔でいっぱいでしたが、経験から大きく2つのことを学びました。
- 新しいコードを書くとき、何をしているのか、しっかりと理解する
- 疑問や違和感を放置しない
当たり前のことですが、そもそも私が、当たり前のことを当たり前にできていなかったということでもあります。この件を自分への楔とし、今年は去年より良いコードを書いていこうと思います。