これはドリコム Advent Calendar 2016 23日目です。
22日目は中西さんの「新卒エンジニアがUnityでバンプマッピングに挑戦してみた」です。
今日はプロセスの曼荼羅についてお話しします。
はじめに
ドリコムの広告事業部ではElixirでAPIサーバーを構築・運用しています。
ElixirはErlangVM上で動作するプログラミング言語です。
Elixirによる開発・運用を行うには、Erlangのプロセスについての理解が必要となります。
この記事ではErlangVM上のプロセスがどういう構造を持っているかについて説明します。
曼荼羅とは
曼荼羅とは仏教における世界観や悟りに対する観念を、仏像やシンボルで抽象化した表現の1つで、日本においては仏教の世界観を表現した絵画を指す事が多いです。
形態、種類、用途は様々なのですが(詳しく知りたい方は「図解 曼荼羅入門 (角川ソフィア文庫)」がお勧めです)、(1)複数のシンボル(仏や幾何学模様)から構成される、(2)各構成要素の関係性に基づく何らかの意図や意味を持って配置される、という共通点があります。
個人的な意見なのですが、ErlangVM上のプロセスの関係に似ていませんか?
Elixirの要素
observer
Elixir(Erlang)はサーバーモニタリングツールのobserverを持っています。便利なので皆さんも良く使っているのではないでしょうか。

observerのapplicationタブを見ると、ErlangVM上で動作しているアプリケーションとそのプロセスツリーが表示されます。この様にElixirは、複数のプロセスがN分木の構造でアプリケーションを構成し、複数のアプリケーションが互いに協調しながらErlangVM上で動作します。

- elixir: Elixir本体
- iex: ElixirのインタラクティブShell
- kernel: Erlangのカーネル
- logger: Elixirの標準Logger
ご覧の通り、Elixir自身もアプリケーションとしてErlangVM上で実行されているのです。
ノード
Elixirにおけるノードは、動作中のErlangVMの事を指します。
分散アプリケーションは複数のNodeが互いに協調しながら処理を行いますが、今回は1Nodeのアプリケーションを前提とします。
アプリケーション
アプリケーションはErlangVM上で実行される一連の処理の塊です。
observerの例では、elixir,iex,kernnel,loggerの4つのアプリケーションがErlangVM上で実行されています。
プロセス
Elixirにおけるプロセスは、OSのプロセスとは別のものです。
プロセスは軽量でオーバーヘッドが小さく、他のプロセスとメッセージをやりとりして処理を進めます。
Elixirでは並行プログラミングを行う上でアクターモデルをベースに処理を記述しますが、このプロセスをアクターとして処理を記述します。
データの取得方法
これらプロセス、ノード、その関係性(リンク)といった情報は取得関数が用意されているので、簡単に取り出せます。
ノード情報の取得
自身のノード:

全ノードのリスト:

アプリケーション情報の取得

プロセスの取得
全プロセスの取得:

プロセスの情報:

プロセス間のリンク情報:

プロセス識別子
プロセスは

という様に3つの整数からなるIDを持ちます。このIDを使ってプロセスを識別できますが、判り易い名前をつける事もできます。
(なお3桁の数字の1つ目がノードの、2,3つ目がプロセスの識別子となります)
プロセス識別子からプロセス名の変換

で変換できます
曼荼羅
さて、ここから曼荼羅的になってくるのですが、この一連のプロセス群の中心には何が在るでしょうか?
全てのプロセスは、アプリケーションコントローラーのプロセスから始まります。
このアプリケーションコントローラープロセスがそれぞれのアプリの大本となるアプリケーションマスターのプロセスを生成管理します。
そしてこのアプリケーションマスターが関連プロセスを生成し、実際の処理を行います。

この様に、ErlangVM上のプロセス群はアプリケーションコントローラープロセスをルート、その子にアプリケーションマスタープロセス、孫以下はプロセスを要素とする木構造を持っています。
可視化
d3jsを使ってErlangVMからプロセスの情報を表示するアプリを
process_mandara
に作成しました。
曼荼羅化の戦略
可視化の為に必要な情報は、プロセスのリスト、プロセス間のリンク情報 の2つです。
また、プロセスが作成(spawn)、削除(exit)されるイベントを監視し、websocket(PhoenixChannel)でリアルタイムに反映させます。
プロセスのイベント監視
Erlangのプロセスのイベントは、trace関数を使って監視します。
tracerを有向にすると、プロセスの発生(spawn)、削除(exit)が発生する度に、メッセージが送信されます。
それをトリガーにPhoenixChannelでメッセージを飛ばしてグラフを更新させています。

出来上がった曼荼羅
曼荼羅アプリの起動

アプリケーションコントローラー付近

全体

参考情報
まとめ
Elixirのプロセスの構造について紹介しました。曼荼羅感をお伝えできたでしょうか?
明日は尾崎さんの「クリスマスカードを作りながらキャラクターデザインについて学んでみよう」です。