Goal
Supervisorのworker/3とsupervisor/3の使い分けについて理解する。
また、start_link/2とsupervise/2の使い分けについても少々。
また、start_link/2とsupervise/2の使い分けについても少々。
Dev-Environment
OS: Windows8.1
Erlang: Eshell V7.2.1, OTP18
Elixir: v1.2.0
Erlang: Eshell V7.2.1, OTP18
Elixir: v1.2.0
Context
ふと疑問に思ったんです。
Supervisorを使うときに、workerで登録しているものとsupervisorで登録している違いって何?っと…
基本的なことなんでしょうけど、実は意識してなかったので知らなかったのです。
そういうわけで、本日は時間も取れないので疑問の解消をちゃちゃっとしてしまいます。
Supervisorを使うときに、workerで登録しているものとsupervisorで登録している違いって何?っと…
基本的なことなんでしょうけど、実は意識してなかったので知らなかったのです。
そういうわけで、本日は時間も取れないので疑問の解消をちゃちゃっとしてしまいます。
Example:
children = [
supervisor(ExampleApp.MySupervisor, [[name: ExampleApp.MySupervisor]]),
worker(ExampleModule, [[], [name: ExampleModule]])
]
例の通りなのですが…
まずsupervisor/3ですが、これはスーパーバイザ(監視者)の定義を行っているものになります。
worker/3は、GenServerやGenEventなどで実装したモジュール(労働者)を定義しています。
まぁとりあえず、スーパーバイザを定義するならsupervisor/3使って、
それ以外はworker/3使ってれば大丈夫でしょう。
まずsupervisor/3ですが、これはスーパーバイザ(監視者)の定義を行っているものになります。
worker/3は、GenServerやGenEventなどで実装したモジュール(労働者)を定義しています。
まぁとりあえず、スーパーバイザを定義するならsupervisor/3使って、
それ以外はworker/3使ってれば大丈夫でしょう。
次、start_link/2を使う場合とsupervise/2使う場合の違いについて…
Example:
これと
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
これの
supervise(children, strategy: :one_for_one)
使い分けは?
とりあえず、Elixirのソースコードを見に行く…
とりあえず、Elixirのソースコードを見に行く…
Quote:
- start_link/2
@spec start_link([Supervisor.Spec.spec], options) :: on_start
def start_link(children, options) when is_list(children) do
spec = Supervisor.Spec.supervise(children, options)
start_link(Supervisor.Default, spec, options)
end
start_link/2の中でsupervise/2呼んでるやん…
- supervise/2
@spec supervise([spec], strategy: strategy,
max_restarts: non_neg_integer,
max_seconds: non_neg_integer) :: {:ok, tuple}
def supervise(children, options) do
unless strategy = options[:strategy] do
raise ArgumentError, "expected :strategy option to be given"
end
maxR = Keyword.get(options, :max_restarts, 3)
maxS = Keyword.get(options, :max_seconds, 5)
assert_unique_ids(Enum.map(children, &elem(&1, 0)))
{:ok, {{strategy, maxR, maxS}, children}}
end
さて…よう分からなくなってきたぞ。
公式のSupervisorのドキュメントには以下のように書いてある。
公式のSupervisorのドキュメントには以下のように書いてある。
Quote:
Module-based supervisorsIn the example above, a supervisor was dynamically created by passing the supervision structure to start_link/2.
However, supervisors can also be created by explicitly defining a supervision module:
Google翻訳するとこんな感じになる。
上記の例では、スーパーバイザは動的をstart_link/2する監督構造を渡すことによって作成されました。
しかし、上司はまた明示的に監視モジュールを定義することによって作成することができます。
答え書いてありますね。
しかし、上司はまた明示的に監視モジュールを定義することによって作成することができます。
明示的に監視モジュールを定義する場合は、supervise/2を使えばいいと…
Quote:
- start_link/2
import Supervisor.Spec
children = [
worker(ExampleModule, [[:hello], [name: :example]])
]
# Start the supervisor with our one child
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
- supervise/2
defmodule MyApp.Supervisor do
use Supervisor
def start_link do
Supervisor.start_link(__MODULE__, [])
end
def init([]) do
children = [
worker(ExampleModule, [[:hello]])
]
supervise(children, strategy: :one_for_one)
end
end
childrenに定義した監視対象を登録するときにsupervise/2をして、
監視を開始するときにstart_link/2を使えばいいってことかな…
何にせよ、今日はここまで…
監視を開始するときにstart_link/2を使えばいいってことかな…
何にせよ、今日はここまで…
間違っていればいずれ気づくでしょう…(致命的なミスにならないことを祈る)
Supervisor面白いな早く自在使えるようになりたい…こんなこともできるってことですよね。
Supervisor面白いな早く自在使えるようになりたい…こんなこともできるってことですよね。
親Supervisor
|-モジュール
|-Supervisor
| |-モジュール
| |-Supervisor
|-Supervisor
少しは成長できた…と思いたい(願望)
ノシ
ノシ