spec」をもとに加筆・補正し、文章を整えました。v1.5から改められました。specの機能とどのように使えばよいのかについてご説明します。specは、つぎのように書いていました。スーパーバイザーはSupervisor.Spec.supervisr/2、ワーカーならSupervisor.Spec.worker/2でそれぞれ子の仕様を定めたわけです。:one_for_one)これでは間違って記述してしまうかもしれません。スーパーバイザーのMyApp.RepoにSupervisor.Spec.worker/2を呼び出したり、ワーカーのはずのMyApp.MyServerをSupervisor.Spec.supervisor/2で起動するというミスが起こりやすいです。どちらで使うかは、モジュールごとに予め決まっているのが通常でしょう。子を起動するときに考えるものではありません。子のタイプを指定する:typeオプションだけでなく、:startや:restartについてもおおむね同じです。多くの場合はモジュールを書くときに定めておくべきで、子を起動する段階で決めることではありません。specはモジュールの構成に含まれるということです。v1.5からこの考え方が採り入れられました。モジュールにchild_spec/1という関数で子の仕様は決めておきます。そのため、子の起動はつぎのように書くだけで済むのです。:one_for_one)スーパーバイザーが動き出すと、リストに納められた子のすべてに対して、各モジュールのchild_spec/1関数が呼び出されます。specが得られ、それぞれのプロセスが起動するのです。指定したモジュールがchild_spec/1を実装していない場合は、エラーになります。specが合理化されたため、Supervisor.Specは非推奨となりました。Supervisor.child_spec/2を使うとよいでしょう。specが定められます。タプル形式より省略ができるので楽になるでしょう。GenServerはchild_spec/1を実装するもっとも、毎回child_spec/1を定義するのは面倒です。GenServerで自動的にchild_spec/1が実装されます。:workerに定めます。GenServerに引数を追加するだけです。}child_spec/1関数は、GenServerだけでなく、Supervisorを使ったときも自動的に定められます。:supervisorです。モジュールベースのスーパーバイザーを定義するときには便利でしょう。}既存のモジュールもchild_spec/1を実装する既存のAgentやRegistry、あるいはTaskといったライブラリもchild_spec/1を実装します。つぎのように書けるということです。Supervisor.Spec.worker/2を呼ばなくて済みます。specが合理化され、モジュール側にchild_spec/1で仕様が定められます。必要な場合には、モジュールにchild_spec/1を定義しておくのがいいでしょう。GenServerなどchild_spec/1が自動的に定義されるときは、適切に引数を渡すだけで構いません。specを定義すれば、指定の間違いが避けられます。有効に活用していきましょう。株式会社gumiのエンジニアによる技術記事公開やDrinkupイベントなどの技術者交流を行うアカウントです。Blog株式会社gumiのエンジニアによる技術記事を公開しています。Blog@gumigumiのエンジニアによる技術記事を公開しています。[Follow]して最新情報をご入手ください。