ずっとJava一筋で生きてきた僕が、最近Elixirに興味を持って色々触っています。
そんな中、色々なところで「OTPが強力」「OTPイケてる」みたいに言われていて、OTPってなんなんだろうとちょっと調べてみたんですが、結局わかったようなわからないような気持ちにしかなれませんでした。
ので、僕自身の理解向上と、そして僕みたいな迷える初心者さんたちのために一度ちゃんと調べたうえでまとめてみようと思いました。
まだまだ浅い理解で書いているので誤った記述もあるかもしれませんが、その際はご指摘いただければ幸いです。
また、具体的な活用方法など詳細については詳しい方々に譲るとして、今回はあくまで概略をざっくり書いていきます。
記事執筆にあたり、下記記事とすごいE本、『Programming Elixir』、あと公式サイトなどを参考にさせていただきました。
[翻訳] ElixirにおけるOTPの紹介
Elixir の OTP (GenServer 編)
OTPとは
OTPとは「Erlangのライブラリ集」、さらに言えば「それらを用いた並行プログラミングをしていくためのフレームワーク/デザインパターン」のようです。
正確な表現ではないかもしれませんが、そのように理解するのが個人的に一番しっくりきました。
厳密にはErlangコンパイラやErlangで書かれたリアルタイムデータベースであるMnesiaなどなども含んでいる(このへんが理解を難しくしているような気がする)のですが、通常OTPという時は前者の意味で言うのが一般的なようなので、ここではもうその前提で進めます。
ちなみにOTPはOpen Telecom Platformの略で、もともとは電話交換機のシステム構築のために作られたためこのような名前になったものの、現在では名称そのまま、より広い用途で使われるようになったという経緯があるらしい。
・・・ので、名称から意味を類推しようとするとドツボにはまる(経験者談)。
Behavior(ビヘイビア)
OTPではOTP内のモジュールを使った便利な定番パターンのことを「ビヘイビア」という名前で定義していて、これらを使うことでElixir(本来はその派生元であるErlang)の並行処理や堅牢なプロセス監視を簡単に実現することができます。
OTPの代表的なBehavior
これらについては参照元にも詳しく書いてあるのでサクッと流します。
-
GenServer
Elixirの軽量プロセス内で状態(state)を扱うためのBehavior。
メッセージパッシングで軽量プロセスに保持しておきたい状態を送って、必要な時に(同じくメッセージパッシングで)取り出すことができる。
状態が不要になったらGenServerのプロセスごと破棄すればGCの対象になって勝手にお掃除してくれる。 -
Supervisor
(例えば上記のGenServerのような)プロセスを監視するBehavior。
Elixirではプロセス上でエラーが発生したら、プロセス内でエラーハンドリングをするのではなく、もうプロセスごとクラッシュさせてしまって、それを監視するSupervisorでプロセスを再起動するなり、なにかしらエラーメッセージを吐くなりさせることが推奨されています。
つまり、実処理とエラー時の対応を完全に分離させることができるわけですね。
ちなみにSupervisorというのはシステム上にただ一つだけ存在する、というものではなく、Supervisorを監視するSupervisorを作成するなど、Tree上に監視体制を構築することが可能です。
以上、本当に簡単になってしまいましたが今回はこの辺りで。