Fork me on GitHub

OTP スーパーバイザ

和訳が古くなっている可能性があります。
いくつかの変更が翻訳元の文書に適用されています。

Supervisor(スーパーバイザ)は、他のプロセスを監視するという、1つの目的に特化したプロセスです。子プロセスが失敗した際に自動的に再起動させることによって、耐障害性の高い(フォールトトレラントな)アプリケーションを作ることを可能にします。

目次

設定

Supervisor の魔術は Supervisor.start_link 関数の中にあります。スーパーバイザプロセスと子プロセスを開始するのに加えて、子を管理するためにスーパーバイザが使用する戦略を定義することができます。

子プロセスはリストと、 Supervisor.Spec から取り込まれた worker/3 関数を使って定義されます。 worker/3 関数はモジュール、引数、そして一連のオプションを受け取ります。内部では、 worker/3 は初期化時に、与えられた引数を用いて start_link/3 を呼び出します。

OTP の並行性レッスンで実装した SimpleQueue を用いて、始めていきましょう:

import Supervisor.Spec

children = [
  worker(SimpleQueue, [], name: SimpleQueue)
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

プロセスが停止したり終了させられたりすれば、スーパーバイザは何事もなかったかのように自動的にプロセスを再起動するでしょう。

戦略

今のところ、スーパーバイザが利用可能な4つの異なる再起動の戦略があります:

リスタート値

子プロセスの衝突を処理する方法はいくつかあります:

これは必須ではありません。デフォルトは :permanent です。

入れ子

ワーカープロセスに加えて、スーパーバイザーにスーパーバイザーの木構造を生成するように監督することもできます。異なるのは worker/3supervisor/3 に替えることだけです:

import Supervisor.Spec

children = [
  supervisor(ExampleApp.ConnectionSupervisor, [[name: ExampleApp.ConnectionSupervisor]]),
  worker(SimpleQueue, [[], [name: SimpleQueue]])
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

Task スーパーバイザ

Task はそれ専用のスーパーバイザ、 Task.Supervisor を持っています。動的にタスクを生成するために設計されており、スーパーバイザは内部では :simple_one_for_one を用います。

セットアップ

Task.Supervisor の取り込みは、他のスーパーバイザと違いはありません:

import Supervisor.Spec

children = [
  supervisor(Task.Supervisor, [[name: ExampleApp.TaskSupervisor]])
]

{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)

監督された Task

スーパーバイザが開始された状態で、 start_child/2 関数を用いて監督されたタスクを作ることができます:

{:ok, pid} = Task.Supervisor.start_child(ExampleApp.TaskSupervisor, fn -> background_work end)

タスクが途中で停止する場合、再起動が行われます。これは次々と入ってくる接続や、バックグラウンド作業の処理を扱う場合には特に役に立つでしょう。


Contributors

loading...



このページをシェアする