[Elixir in Action]fault toleranceを保つための特別な責務を負うprocess~Supervisor~

BEAMの真骨頂であるFault toleranceに関して、複数章に渡って説明しているところの話。
ここではその触りの箇所。

fault torelanceであるようにするためには、failureを知り、それに対してリカバリして現状の機能を提供し続けることが最低限必要です。そのためにBEAMがどのような機構を備えて、Elixir/Erlangではどうなのか?をまとめています。

3つのタイプのエラー

BEAMでは3つの種類のerrorを持ちます。

  • errors
    • ** [ArithmeticError] bad argument in arithmetic expression などで意図せずエラーがでるとき
  • exits
    • exit("I'm done") のように、意図的にプロセスを終了させる
  • throw
    • throw(:throw_value) のように、意図的にthrowを投げる
    • throwの目的は、non-localな相手へ何か情報を与える時に使うことです。(BEAMでは、remote processに何か処理を任せる、ということが多々ありますね)

Elixirでは、すべてのエラーは 必ず 何らかの値を返します。
そのため、任意のエラーに対して共通で何かする、というときは以下のように _ を使う必要があります。

try do
  raise("something went wrong")
catch
  _, _ -> # エラー時の処理
after
  # あとしまつ
end

それ以外では、 catch のパターンマッチを使い、特定のエラーの時は意図した処理を行うような処理を書きます。
defexception により、任意のmacroを組むことが可能。

もし、エラー処理を用意していない場合、 processはterminate されます。制御できないエラーはどんどん落としてしまえ、というやつですね。

errors in concurrent system

BEAMではprocessで分離しているので、何らかのprocessのエラーが他processへ影響を与えることはありません。
そのため、processを監視して、互いを把握していく必要があります。

Link

Process.link/1spawn_link/1 を使うことで、2つの異なるprocessをリンクします。リンクするとは、一方のプロセスが死んだら、もう一方はそれを知ることができるし、その逆も然り、という相互の関係を持つことを指します。
正常にexitするときは :normal という値を返します。それ以外は、基本的に異常終了である、と判断します。

通常、終了のシグナルは以下のメッセージを構成します。

{:EXIT, from_pid, exit_reason}

何らかのエラーを投げて死ぬ場合は、以下の形式のメッセージを構成します。

{reason, where}

Monitor

Process.monitor というのも提供しています。これは、あるprocessを監視する、という一方通行の監視になります。さらにErlangの資料には以下のように書かれています。

http://www.erlang.org/doc/man/erlang.html#monitor-2

The monitor request is an asynchronous signal. That is, it takes time before the signal reach its destination.

このように、 何らかのprocessを監視し、crashが発生した時に必要な処理を行う ことに責務を持ったprocessを supervisor と呼びます。

なるほど。Getting startedにも出てきたsupervisorが出てきました。

Supervisor

処理を行うworker processは、基本的にsupervisorによって監視されます。

supervisorは子プロセスにリンクを貼り、監視を行います。supervisorが終了(exit)すると、そのリンクされた子プロセスも終了します。子プロセスがcrashした場合は、適切なstrategyに沿って別プロセスを立ち上げたりします。

supervisorは、 monitorではなくlinkを使います
crashした時に立ち上がるprocessは、pidが異なるプロセスです。そのため、crashしたprocessがローカルに持っている状態は、新しいprocessには共有されません。


なるほどなるほど。
linkの他にmonitorがあること、supervisorとその他のprocessの責務の整理が進みました。
次の章ではさらに踏み込んで説明されるので面白そう。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中