3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-11-30

#スーパーバイザー

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)子サーバのリストを渡し, オプションを設定する。

###実行してみる

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

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?