#スーパーバイザー
Elixirの方針としてエラーハンドリングをするのではなく, 死んだプロセスを監視しておき
再起動, するという方針である。
プログラミングElixirにスーパーバイザーについてわかりやすく書いてあった。
##監視しているプロセスが死んだ際にどうなるのか
###コード
スーパーバイザー側のコード
defmodule Sequence do
use Application
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = [
worker(Sequence.Server, [123])
]
opts = [strategy: :one_for_one, name: Sequence.Supervisor]
{:ok, _pid} = Supervisor.start_link(children, opts)
end
end
worker
defmodule Sequence.Server do
use GenServer
def start_link(current_number) do
GenServer.start_link(__MODULE__, current_number, name: __MODULE__)
end
def next_number do
GenServer.call __MODULE__, :next_number
end
def increment_number(delta) do
GenServer.cast __MODULE__, {:increment_number, delta}
end
def handle_call(:next_number, _from, current_number) do
{ :reply, current_number, current_number+1 }
end
def handle_cast({:increment_number, delta}, current_number) do
{ :noreply, current_number + delta}
end
def format_status(_reason, [ _pdict, state ]) do
[data: [{'State', "My current state is '#{inspect state}', and I’m happy"}]]
end
end
イベントの流れとして
- スーパバイザー側のstart関数が呼ばれる
-
children
に監視対象となるSequence.Server
を開始し、123の引数を渡す -
Supervisor.start(children, opts)
子サーバのリストを渡し, オプションを設定する。
###実行してみる
Takuya@Takuya-no-MacBook-Air:~/sequence iex -S mix
Erlang/OTP 19 [erts-8.0.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.3.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Sequence.Server.increment_number 3
:ok
iex(2)> Sequence.Server.next_number
iex(3)> Sequence.Server.increment_number "cat"
:ok
iex(4)>
02:03:33.524 [error] GenServer Sequence.Server terminating
** (ArithmeticError) bad argument in arithmetic expression
(sequence) lib/sequence/server.ex:21: Sequence.Server.handle_cast/2
(stdlib) gen_server.erl:601: :gen_server.try_dispatch/4
(stdlib) gen_server.erl:667: :gen_server.handle_msg/5
(stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Last message: {:"$gen_cast", {:increment_number, "cat"}}
State: [data: [{'State', "My current state is '127', and I’m happy"}]]
Sequence.Server.next_number
123
iex(5)> Sequence.Server.next_number
124
###結果
Sequence.Server.increment_number
に文字列を与えていると
エラーレポートを表示している。
そして次に呼び出した際には, Sequence.Server.next_number 123
が帰ってきている。
これはプロセスのエラーレポートを表示し, スーパーバイザーがプロセスを再起動しているからである。
プロセスが死んだ場合, 再起動していることはわかった
しかし 123が帰ってきたのは前のプロセスの状態を持てず, 再起動前の記憶を持てないからである。
このままではエラーが起きた場合は, 以前の状態の記憶がない状態になっている。
それを防ぐために, 状態をstashしておくことが必要になる。
次は再起動をまたいだプロセスの状態の管理を見ていく。