RuboCopの実行がOOMに殺されて1ヶ月が過ぎました
これはSmartHRアドベントカレンダー2日目のエントリです。
私の所属先であるSmartHRではCircle CIを使ったCI環境を用意していて、その中でRSpecやRuboCopを実行しています。
そんななか、たまにRuboCopのjobがReceived "killed" signal
と発して死んでゆく現象が発生していました。
しかも、なんとなく発生頻度が高まっているような……?という気がしてきて地味に困るので調査を開始しました。死亡現場である動作ログをよく見るとRuboCopの検査自体は終了しているように見えるものの、その後のなんらかの処理で死んでいる*1ように見えました。
RuboCopの実行後の処理とは
CircleCIではJUnit形式で実行結果を出力しておくと違反があったときいい感じにしてくれる機能があるため、例に漏れず我々のプロダクトでもJUnit形式のXMLを出力していました。
(📝 RuboCopでは0.80.0からJUnit用のフォーマッターを内蔵するようになったので、rubocop-junit-formatterなどの専用gemを使わなくても良いようになっています)
処理の流れをエスパーするに、おそらくこの処理で長大なXMLを生成しようとして力尽きているのでは……と予想を立てました。
で、どうしたの
どうしようかなあと困っていたのですが、RuboCopのチェンジログを眺めていると0.85.0*2
で--display-only-failed
というオプションが追加されていることを知りました。これはJUnit形式のXMLを生成する際に利用できるオプションで、失敗したものだけをXMLに出力するという大変省エネなオプションです。
use --display-only-failed
見立て通り死因がOOMであればこのオプションは有効であろうと思われるので、早速このオプションをCircleCIのconfig.ymlに追加しました。
すると、目に見える効果としてRuboCopのジョブ自体の実行時間が結構減りました(具体的には4〜5分だったものが1〜2分で終わるように)。
そして、数日の間CircleCIの結果を眺めていたところ、RuboCopの不審死は見当たらなくなりました。
どうやら問題は解決できたようです。やったね🎉
というわけで
人間は慣れてしまうもので、ちょっと不便だな〜というものはそのままにしがちなのですが、ちゃんと調べたら解決できることもあるので、面倒がらずに調べてみると良いですね。
特にCIの設定は一度設定するとあまり注視しないものなので、効果的な設定があってもそのままにされがちだったりします。たまには設定の棚卸しをすると良いかもしれませんね。
*1:killが送られてきているので、OOMっぽいなと当たりをつけました
*2:https://github.com/rubocop-hq/rubocop/blob/master/CHANGELOG.md#0850-2020-06-01