Designing for Scalability with Erlang/OTPを読みました。Erlang/OTPを軸とした、スケーラブルなシステムを構築するための設計に必要な知見がたまってそうだったのと、半額程度で購入できたのでありがたく読みました。 内容として、半分はErlang/OTPのエコシステム周り、設計思想とかの話でした。ただ、残す半分はErlangに限ったことではない、広く使えそうな基礎がまとまっていました。個人的には、Elixir in Actionと合わせて読むとこの系統の書籍は十分そうな感覚です。 ちなみに、所どころ使われている例題や、それを個人的にElixirに書き直したものを以下に置いています。(所どころ壊れているものもありますが。) https://github.com/KazuCocoa/erlang-scalable-design 前半部分 Erlang/OTPの全体的な話が書かれています。背景とか。message passingの概要とか。諸々。Erlangの文法も学びながら、gen_serverだったり、gen_fsmだったりといくつかのOTPの話に発展する感じでErlangを学ぶことができます。 debugのための、sysやdbgモジュールも記載されていました。以前読んだQiitaのReconTrace で Erlang VM のトレース機能に親しむでかかれていたrecon_traceなんかのことも言及されています。 proc_libという特別なプロセスの話も。この特別なプロセスは、 システムメッセージや、イベント、シャットダウンとが可能 動的モジュールのリストを得ることができる debug flagを使ってトレースメッセージを利用することができる といった特徴があります。 後半部分(Chapter13以降くらい) Chapter 13のDistributed Architectureは、SOAやP2Pといった大局な設計やinterfaceから、その配布方法などの話まで色々ありました。これはErlangに特出したツールの話以外は、普通にErlang以外でも役立ちそうな情報だと思います。 リリース関係の話の中で、riakというdecentralized datastoreなツールの話もあって、面白かったです。Gossip protocolを使ってClusteringしているとか、そういう話も載っていたので。HashiCorpのSurfなんかでも結構知られていますね。Gossip protocol。 Riakのそこらへんのドキュメントはこちら http://docs.basho.com/riak/latest/theory/concepts/Clusters/#Gossiping http://docs.basho.com/ これのErlang client https://github.com/basho/riak-erlang-client Elixir client https://github.com/drewkerrigan/riak-elixir-client Scalableなシステムを組むためのtipsとして、以下の項目がまとめられていました。 分割する Distributed architectural pattern(cluster, SOAなど ) Network protocol node間のinterfaceや状態も持ちようやデータモデル node間のretry strategy node間のsharing data…More
Tag Archives: elixir
[Elixir][Erlang]RecordとElixirのStructの違い
最近、Erlangのある書籍を読み始めました。そこでは始めの方にErlangの基本的な事柄が書かれていたので、そこを軽く追いながらErlangを軽く学んでいます。(と言っても、Elixirやってきたので文法以上は特に目新しいものはないのですが) そこで、ElixirのStructとElixir/ErlangのRecordの違いが気になったので、まとめておきます。 結局は、RecordとMapの違いになってきて、Erlangコミュニティで話されるその違いと同じような感じになっていました。(すごいE本のP. 567とか。やっぱりこの本、すごい。)ただ、ElixirのStruct自体はElixir独自のものなので、ちゃんと残しておきます。 Erlang x Record Erlangでは、Recordはtupleの糖衣構文。例えば、以下の通り を実行すると以下の結果になります。 なるほど。 Elixir x Record なるほど。でも、こう見るとこれはstructに似ている。と思いますよね。普通にElixirのget startを学んだだけだとRecordがでてこないので、考える順としてはこんな感じだと思われます。 ElixirのRecord ElixirのRecordのドキュメントを見ると to work with short, internal data to interface with Erlang records と、Recordの使うポイントが書かれています。ふと、ここでよく見るとstructとの使いわけが気になります。 まぁ、そう思うよね、と思ったらGoogle Groupsにやっぱり。 https://groups.google.com/forum/#!topic/elixir-lang-talk/6kn7J2XnFg8 https://gist.github.com/josevalim/b30c881df36801611d13 結論だけここに残しておくと、たいていの場合はStructを使って、限られたときだけRecordを使いましょう、というもの。StructはMapで __struct__ 定義されます。 To clarify: when we said that Records in Elixir were deprecated, it was Elixir implementation of records which is…More
[Elixir]Lint with dogma
Elixirのlintツールとしてdogmaというものがあります。 RubyのRobocopのようなものですね。 https://github.com/lpil/dogma 試しに適用してみました。修正も。備忘録に、以下2つ。Phoneixの簡単なアプリとhttp_proxyを。 http_proxy https://github.com/KazuCocoa/http_proxy/pull/21/files sample web app https://github.com/KazuCocoa/web_qa_vote/pull/6/files Report formatとしてJSONもしてい出来ます。 https://github.com/lpil/dogma/blob/master/docs/reporters.md この標準出力を解析して、例えば dokumi と組み合わせるとPR時にlintを指摘する、というのもできますね。 ※ 最近は credo を私は使っているMore
[Elixir]ExUnitで同名のtestが存在した時にコンパイルエラーにする
1行まとめ ExUnitにおけるテストケースの重複時にコンパイルエラーにしたい場合、 test_helper.exs に Code.compiler_options(warnings_as_errors: true) オプションを追加しておこう 多分、これはチーム開発では大いに役立ちます ExUnitが test マクロを関数定義するまで 以下のようなテストケースがあったとします。 この時、 test マクロで定義されたところは __ErrorSampleExunitTest__.’:test the truth’ としてコンパイル時に定義されます。 Elixir1.2.1では以下の行での話になります。 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L258 同名の test が存在した場合 さて、この時に複数の同名のテストが存在した場合はどうでしょう? 例えば以下。 この場合、コンパイル時にCLIで以下のような warn が表示されます。 test/error_sample_exunit_test.exs:8: warning: this clause cannot match because a previous clause at line 4 always matches テストケースを記述するコードは、 .exs の拡張子を持つので、このようなwarnはテスト実行毎に表示されます。なので、実行を注意深く見ていると、このエラーを知ることができます。 ただ、他のテスト自体は実行されます。 コンパイルエラーにする ただ、warnではなくコンパイルエラーにしたほうが親切なのでは?と思い、手元でコンパイルエラーになるようにExUnitを直接修正してみました。 ExUnitのtestマクロでは、以下の2点でコンパイル時に関数を定義します。 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L258 https://github.com/elixir-lang/elixir/blob/v1.2.1/lib/ex_unit/lib/ex_unit/case.ex#L280 なので、その直前で以下のように既存モジュールに定義済みの同名関数があるかどうかを検出させ、trueであればraiseするようにします。 コンパイラオプションで回避する…More
[Elixir]CustomLoggerのコードを追う
[Elixir]Loggerのconsole出力をファイルに書き出すではlogger_file_backendを使う、ところを残しました。そのついでに、CustomLogger付近とその作り方を見てみました。 参考: Elixir Meetup #1 Loggerの構造と拡張 from Sugawara Genki これを理解するために、ElixirのLoggerの実装群や、 GenEvent 付近が理解を助けてくれます。 https://github.com/elixir-lang/elixir/tree/v1.2.0/lib/logger/lib Elixir本体のloggerの参考 https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/logger/lib/logger/backends/console.ex :console のbackendの書き方の参考 このようにしてcustomer loggerを作り、backendとして指定、利用できる https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/logger/lib/logger/formatter.ex log levelの種類によって表示を整形する参考 https://github.com/elixir-lang/elixir/blob/v1.2.0/lib/elixir/lib/gen_event.ex Backendの拡張のために利用される 私も参考で貼ったスライドを参考に、練習のためにCustomLoggerを書いてみました。consoleの実装箇所を参考にすればここら辺もかける感じ。 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden…More
[Elixir]Loggerのconsole出力をファイルに書き出す
少しLogに関する知見を得たので、 logger_file_backend とか使ってみることにしました。後でちゃんとCustomLoggerの知見を貯めておこう。 経緯 通常、Loggerはconsoleに書き出されます。しかし、そのままではIOが大変ですし、ファイルに書き出したりしていきたいです。そのため、ログをファイル出力する形にしたいなーと考えていました。 CustomLogger ElixirのLogger のドキュメントを少し読んでみると、デフォルトでは :console としてコンソールに結果が出力され、そこからカスタムするときはCustomLoggerを作れるよ、と書いています。 Custom backends を読んでみると、 GenEvent を使ってCustomLoggerを作ることができるのですね。そこで簡単なファイルへ書き出すCustomLoggerを作ろうとは思ったのですが、通常のLoggerの結果をファイルに書き出す、というシンプルなreposirotyを見つけたので、ひとまずはそれを使ってみることにしました。 Logger_file_backend Logger_file_backend https://hex.pm/packages/logger_file_backend https://github.com/onkel-dirtus/logger_file_backend 他に、Erlangのlagerをラップしたexlagerというのもあるのですが、Phoenixと一緒に使う方法とか探しているとElixirに組み込まれているLoggerを操作する系の方が安易だったので見送りました。 exloger https://github.com/khia/exlager 参考 elixir in production from Tsunenori Oohara 導入した時の、サンプルプロジェクトのコミット https://github.com/KazuCocoa/web_qa_vote/commit/035f5cd6e451cd84d5c3e4304cc0853e8ccf0672More
[Elixir]tear down in ExUnit as on_exit
teardownを探していたのですが、 ExUnit では、現在はteardownは on_exit のcallbackで実装されています。過去、この形に変更されたのですね。 http://elixir-lang.org/docs/v1.1/ex_unit/ExUnit.Callbacks.html#on_exit/2 使い方は以下。 setup の中で on_exit を定義します。これで、この setup_all や setup と同じサイクルで処理が実施されます。 ちなみに、 shouldi を使った時は上手く動作しなかった… 過去、私も書いていた… MIX AND OTP vol 1More
[Elixir]about parameterized test with Elixir(Eng ver)
Previously, I published support library to do parameterized test with Elixir on hex and WordPress. See here, but it in Japanese. The library is simple macro. So, anyone can use it easily. See readme and docs if you would like to know more hex https://hex.pm/packages/ex_parameterized GitHub https://github.com/KazuCocoa/ex_parameterized Example This file contains hidden or bidirectional Unicode…More
[Elixir]compile timeに決定されるモジュールの定数
Elixirでは以下のように @neko と定義することで、このモジュール内で共通して使える要素を定義できます。最近使い方を誤ってしまったのですが、この値はコンパイル時に決定されるので、それ以降に読まれる値を設定することはできません。 In other words, the value is read at compilation time and not at runtime. As we are going to see, this makes attributes useful to be used as storage during module compilation. http://elixir-lang.org/getting-started/module-attributes.html 例えば、 というような用途では、必ず default が代入されます。 つい忘れていてつまづいたので、メモ…More
[Elixir][Jupyter]Play IElixir on Jupyter
最近、Jupyterを知りました。 Python/Rubyで学んだのですが、Elixirでもあるか探してみたらありました。(なかったら作ってみようとしてた) 使い方は簡単で、Readmeに書いている通りにするだけです。 Jupyter https://jupyter-notebook.readthedocs.org/en/stable/index.html https://github.com/jupyter IElixir https://github.com/pprzetacznik/IElixir IErlang https://github.com/robbielynch/ierlang そのほか、利用可能なKernelは以下 https://github.com/ipython/ipython/wiki/IPython%20kernels%20for%20other%20languages こんな感じで起動できます。 ElixirというかErlang自体、こういう数値計算は得意としない領域なのですが、Elixir/Erlangをブラウザ越しに試す、という環境ではかなり使い勝手の良いものです。 🙂 追記: nbviewerを使えば、GitHub上でコードを簡単に共有もできてとても便利に使えます 🙂 (ただ、Elixir/Erlangは未対応です) http://nbviewer.ipython.org/More