Elixirのスーパーバイザーについて

1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...

スーパーバイザー

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

イベントの流れとして

  1. スーパバイザー側のstart関数が呼ばれる
  2. childrenに監視対象となるSequence.Serverを開始し、123の引数を渡す
  3. Supervisor.start(children, opts)子サーバのリストを渡し, オプションを設定する。

実行してみる

[email protected]:~/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しておくことが必要になる。
次は再起動をまたいだプロセスの状態の管理を見ていく。


1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...
      この投稿は審査処理中  | 元のサイトへ