Slide 1

Slide 1 text

Erlang/Elixirを はじめよう! 2016/11/20 @yutopp A(izu)LT 東京編 0x01

Slide 2

Slide 2 text

目次 ● 自己紹介 ● Erlangを触ってみよう ○ Erlangの特徴 ○ Erlangの疑問点 ○ Erlangを使うためのコツ ● Elixirを触ってみよう ○ お気持ち ● 使ってみた ● まとめ

Slide 3

Slide 3 text

自己紹介 ● @yutopp ● 今年シャカイに出てしまった ● C++とOCamlが好きです! ○ なぜか半年間ずっと Erlangを書いてる

Slide 4

Slide 4 text

Erlangってなに ● 並行処理・分散処理に特化したプログラミング言語 ○ 普段使わない脳の分野を使う羽目になる ● 動的型付き言語 ● 構文はPrologがベース ○ すこししんどい ● "Erlangプロセス"をつかった並行処理が目玉(アクターモデル) ○ 軽量プロセス。これをバンバン使う ● Let it crash戦略とかも特徴的 ○ エラーハンドリングはするものの、プロセス丸ごと殺して回復させたりする ● データ構造は全部 immutable ○ プロセスごとにデータを共有することはない (例外はあるけれど…) ○ KVSとかは別途ある

Slide 5

Slide 5 text

どんなとき便利? ● ユーザーが投げたデータをサーバーで処理しつつリアルタイムに通信する必要が あるようなプログラムを書きたいとき ○ 1ユーザーにつき1つのプロセスを紐つけて、独立して処理させたりできる ● 複数のマシンで分散させて動かすようなプログラムを作りたいとき ○ とくに難しいことをしなくても [要出典]マルチノードで動かせる

Slide 6

Slide 6 text

Erlangプロセス/並行処理って ● プロセス一つ一つが独立して動き出す、クラスのイ ンスタンスみたいなものだと思ってしまおう ● プロセスごとに"メッセージ"を送りあってやりとりする ○ 限定的には、オブジェクト指向でいうメソッド呼び出しみたい なもの[要出典] ○ アクターモデルというやつ ● メッセージが送られると自分のプロセスのメールボッ クスにそれが積まれる ● メッセージがきたら返信してもいいし、捨ててもいい し自由 https://cwiki.apache.org/confluence/display/FLI NK/Akka+and+Actors

Slide 7

Slide 7 text

つまりErlangを書くには ● ステップ1: Actor-modelに慣れる ○ プロセスごとの役割を適切に割り振って、シンプルに協調して動くようにする ○ プロセスごとの関係性を把握できるようにする ○ 同期処理・非同期処理をうまく使い分ける ○ タイミング問題に気がつけるようになる ■ それぞれのプロセスが好き勝手動くので、タイミングによってはバグるとかある ● ステップ2: OTPを使えるようにする ○ 後述 ● ステップ3: Erlang独自の作法に慣れる ○ 書き続けてればなんとかなる … ○ なんとかなってほしい

Slide 8

Slide 8 text

メッセージをやり取りするプログラム -module(sample1). main(_) -> Pid = spawn( fun() -> receive {Sender, yo} -> Sender ! hi end end), Pid ! {self(), yo}, receive hi -> io:format("got reply!~n") end.

Slide 9

Slide 9 text

疑問点 ● プロセスを並行で動くクラスオブジェクトと見立てた場合、このメッセージのやり取り を毎回書く必要があるのか? ○ → 実際はそれはしんどすぎる ● エラー処理とかどうするの ○ タイムアウトとかいろいろある Erlangには、これらの挙動を公式に抽象化した長年の運用実績のあるライブラリがあ る!! OTP (Open Telecom Platform)

Slide 10

Slide 10 text

さっきの例をOTPを使うと… ● さっきの例は、ユーザからメッセージを受け取って返事を返すもの ○ メソッド呼び出しされたら値を返すみたいな挙動してる これはサーバでは?! gen_server ビヘイビア

Slide 11

Slide 11 text

こうなる %% サーバ側 -module(yo_server). -behaviour(gen_server). yo(Pid) -> gen_server:call(Pid, yo). 〜中略〜 handle_call(yo, _From, State) -> {ok, hi, State}. %% クライアント側 -module(sample2). main(_) -> Pid = yo_server:start_link(), hi = yo_server:yo(Pid), io:format("got reply!~n").

Slide 12

Slide 12 text

疑問点2 ● 終了しないプロセスを書いたらどうなるの ○ 永遠に生き続けるので気をつける必要がある ○ プロセスリークと呼ばれる ● やり取りしているプロセスが死んでしまったり、エラーが発生したらどうするの? ○ 直に検知する方法はある ■ リンク・モニタ

Slide 13

Slide 13 text

リンクとモニタ ● リンク ○ プロセス同士を双方向で紐つける ○ 片方が死んだら自分にシグナル (メッセージの強力なやつ )が送られてくる ○ それをハンドルしない場合は自分も巻き込まれて死ぬ ○ 依存の強いプロセスの管理で使う ● モニタ ○ プロセスを単方向で紐つける ○ 監視先が死んでも自分は死なない ○ 監視先が死んだら自分にメッセージが送られてくる

Slide 14

Slide 14 text

OTPを使ってしまおう ● プロセスを野放しにしておくとプロセスリークするので管理する ● リンクやモニタを使って、プロセス同士の依存関係を作って全て監視する ● この仕組みを個々で実装してたら大変すぎ プロセスツリーを作って、プロセスの死を適切にハンドルする枠組み supervisor ビヘイビア http://learnyousomeerlang.com/supervisors# supervisor-concepts

Slide 15

Slide 15 text

supervisorを使うと ● リソースの確保に失敗してどうしようもなくなった。こんなとき ○ 自身のプロセスをクラッシュさせて終わらせる ● 再起動戦略を定義しておけば、supervisorが対象のプロセスを再起動してくれる ○ 次のプロセスはきっとうまくやるでしょう。 ● なんらかのミスでプロセスが落ちたとかそんなときも有効 ● 少なくともどこかしらのsupervisorにプロセスが属するように作れば、プロセスリーク しててもわかる

Slide 16

Slide 16 text

マルチノード ● Erlangは複数のマシンで動かせる ○ Erlangクラスタ ○ マシンごとのErlangVMをノードと呼ぶ ● 別のノードで動いているプロセスとも、普通通りの構文でメッセージのやりとりがで きる ○ リンクもモニタも普段通り ● 別のノードが唐突に落ちた場合には、そのノードで動いていたプロセスが全滅する が、リンクやモニタをしていれば通知がくるので、適切にハンドリングできる ● スケールしやすい[要出典]

Slide 17

Slide 17 text

Erlangまとめ ● Erlangで大事なのは、OTPを学んでみること ○ 上手く使って枠組みに載せるとデカいアプリも作れるようになる ○ 周辺ライブラリもこの作法に従っているので、手が付けやすくなる ○ 分散・並行プログラミングで大事な部品の考え方をここで学ぶ ○ applicationとかgem_fsmとかgen_leaderとかあるよ ● 構文に慣れつつ、OTPの枠組みに乗れれば道は開かれる ○ 最初は出来合いのサンプルをいじっていくと良いと思います。

Slide 18

Slide 18 text

Elixirってなに ● Erlangが動くVMであるBEAMの上で動く言語 ● Erlangを便利に書けるようにした言語という感じ ○ JavaでいうScalaみたいな?でもそこまで新機能があるという感じではない ● Erlangを書いていると不便だったところが改善されまくっている ○ Erlangは1ファイル1モジュールだったり ○ 文字列がデフォルトでリストだったり ○ ビヘイビア実装するのが面倒だったり ○ 動的多態が書きにくかったり ○ → Elixirでは全部解決してる!! ● 基本のライブラリはErlang/OTPまんま

Slide 19

Slide 19 text

Elixir触った感想 ● 個人的に、Erlang/OTP触ってからやったほうが楽だと思った ○ ElixirはErlangの周辺環境を劇的に便利にはしてくれるが、根本のライブラリは OTPまんまなので、 ドキュメントとか使用感とかは Erlangで直に触っておくととっつきやすそう ● Elixirで飛んでくるエラーがErlangまんまのが多くて草 ○ Erlangやってたからパッと気付けるエラーとか結構あった気がする ○ ただ、基本は見やすくなる (どのモジュールで起きたかとか読みやすい ) ● Rubyっぽく書けるけど全然Rubyじゃないので気をつけよう ● Elixirから触るのであれば、何か作りつつ並行プログラミングに慣れていくと楽しそ う ○ PhoenixというWAFがあり、楽しい

Slide 20

Slide 20 text

実際に触ってみた ● 鳥小屋をElixirで作ってみた ○ ユーザーからの入力 ○ サーバーで実行しつつリアルタイムで出力を転送 ○ アクターモデルだと楽に書けそうだった ● デモ(作りかけ) ● 続きはアドベントカレンダーで書きます…

Slide 21

Slide 21 text

まとめ ● 並行・分散システムは普段使わない部分の脳を使う気がして楽しい ○ 個々のプロセスが好き勝手動くので気をつかう ○ OTPがなければ死んでいたというくらい便利ですごい ○ 楽しい ● ぜひ使ってみましょう!!!! ● 初めてElixirから手を付けるなら、phoenixでウェブアッピを書いてみるのをオススメ ○ 必要な部品が大体揃っているので、作りつつ慣れていくのに最適では ○ ただ、あまり分散システムという感じはしない …

Slide 22

Slide 22 text

便利ライブラリ・ツール紹介 Erlang編 ● rebar - erlang用ビルドツール ● cowboy - webフレームワーク ● eunit - 単体テスト ● ct - 結合テスト ● meck - モック ● dialyzer - 型チェッカ ● escript - それとなくerlangを実行できる ● recon - 優秀デバッガ Elixir編 ● mix - elixir用ビルドツール ● phoenix - webフレームワーク ● ecto - ORM ● exunit - 単体テスト

Slide 23

Slide 23 text

おしまい 質問して 参考文献 Learn You Some Erlang for great good! (すごいErlang愉快に学ぼうの英語版) Erlang/OTP Documentation (公式ドキュメント) sile - Qiita (参考になる記事とライブラリいろいろ) 響け!ユーフォニアム2 [最新話無料] - ニコニコチャンネル:アニメ (観て)