Let it crashについて
Elixir/Erlangを勉強してなかった時、c++の例外処理について、例外の安全性の確保が難しいことと例外処理を入れるとコードが理解しにくくなることを認識して、もっと良い手段がないかを調べたら、let it crashという言葉を知り、誤解のままc++のプロジェクト(デスクトップアプリ)で使ってしまいました。例えば、エラー処理するべきところに変なassertを入れて、ユーザーから予想外の操作がされたら思い切り落ちってしまいます。そのあとassertするコードを排除したが、let it crashの概念がずっと誤解したままでした。ElixirでOTPを勉強したら予約let it crashについて少し理解できたので、メモを残ります。
let it crashとは何か?
Erlangでは、不明なエラーが起こったとき、防御的なプログラミングをすることではなく、processをcrashさせる。crashした後、他のmonitor processに教えて、エラーをどう処理するかを決めてもらう。let it crashでは、以下の条件を満たす必要があります。
エラーを処理しないではない
let it crashはエラー処理しないと思ってたが、大きな間違いです。エラー処理しないではなく、プログラマーの代わりにエラー処理を手伝ってくれる「人(process)」がいるのです。
手伝ってもらう前に、crashが起こったことをお知らせする必要があります。erlangでは、linkやmonitorを用いって、crashした情報を外部に通知します。さらに、OTP frameworkでは、この仕組みをもっと抽象化して、supervisorという専用のprocessを提供します。このsupervisor processは他のprocessの管理の仕事がされてます。
supervisorは以下のようなストラテジに従って、processを管理します。
-
one_for_one ある子プロセスが終了したら、そのプロセスだけを再起動します。
-
one_for_all ある子プロセスが終了したら、他のすべての子プロセスを再起動します。
-
rest_for_one ある子プロセスが終了したら、そのプロセスの次のすべての子プロセスを再起動します。
詳しい説明はこちらへ:http://erlang.org/doc/design_principles/sup_princ.html
Processの起動・再起動のoverheadを極小にしなければならない
極端な例で考えると、あるprocessが100万のユーザーとつながっています。このprocessを再起動するのに1秒もかかります。この場合、processを再起動すると、1秒間の間で、100万のユーザーがサービスを利用不可になってしまいます。
Erlangの場合、processの起動のoverheadがすごく小さいので、1ユーザーに対して、1processを起動することがほとんどです。
crashしても他のところに影響を与えない
multi threadの場合、メモリが共有さてたので、一つのthreadがcrashしたら、他のthreadもおかしくなる時がよくあります。この場合、勝手にlet it crashしたら、すべてのデータが壊れてしまいます。
Erlangの場合、actor model+immutable dataのおかげで、crashしてもエラーが隔離されて、他のところに影響を与えなません。
Erlang VM系以外の言語でlet it crashをしたら大体間違い
他の言語では、上のような仕組みをない(akkaを除く)ので、let it crashしたら、ほぼ間違いじゃないでしょう。