ElixirからErlangVMにオプションを引き渡す

Qiitaにて、shibacowさんのElixirでプロセス20万くらい作ってみたという素晴らしいElixirの記事があり、そちらの記事にて最大プロセス数の変更はどのように行えば良いのか自分自身でも気になったため調べたところElixirからErlangVMで生成できるプロセス数を(たぶん)変更できる方法を発見したので記事にしたいと思います。

# 実行環境
OS:OS X Yosemite
Erlang:Eshell V6.5, OTP-Version 18
Elixir:v1.0.4

# まずはErlangでプロセス数の変更を確認
Qittaの記事にも記載されておりますが、 erl(1)のドキュメントには
OTP-R18より +P オプションにてプロセス数の上限の設定は無効化されていると記載されています。ドキュメントはこちら
ただし、実行してみると、どうも動いているようにも見えました。

$ erl
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> erlang:system_info(process_limit).
262144 # Erlangのデフォルトで使用できるプロセス数が表示される

オプションをつけてプロセス数を制限してみる

$ erl +P 1024
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V7.0  (abort with ^G)
1> erlang:system_info(process_limit).
1024 # 設定された値となっている

Erlangのシステム情報としては上記のような結果となりました。
では実際にQittaに記載されているコードでErlangVMにオプションを引き渡しプロセス数を制限したらどうなるかを確認してみます。

# 実行を行うための新規プロジェクトの作成

$ mix new many_process
$ cd many_process
$ vim lib/many_process.ex

ソースコードは Gistに記載されている内容をそのまま使わせていただきました。
https://gist.github.com/shibacow/86c6eba46d12b9f0d395

# ErlangVMに引き渡すオプションを設定し、実行
ElixirからErlangVMへとオプションを引き渡す方法を探してmixなどのドキュメントを探しましたが、これがどこにも記載されていなくて困り果てていたところ
iex --help の結果の一番下に「Options can be passed to the erlang runtime using ELIXIR_ERL_OPTIONS or --erl」と記載されていて、helpかぁ!っとなったりしました。
上記ということらしいので ELIXIR_ERL_OPTIONS を設定し、iex を起動し、コードを実行してみます。

$ export ELIXIR_ERL_OPTIONS="+P 1024"
$ iex -S mix
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Compiled lib/many_process.ex
Generated many_process app
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> ManyProcessFactory.main

22:28:10.083 [error] Too many processes

Too many processesでエラーとなってしまい、落ちてしまいました。

では、今度はプロセス数を増やして実行してみましょう。

$ export ELIXIR_ERL_OPTIONS="+P 300000"
$ iex -S mix
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Compiled lib/many_process.ex
Generated many_process app
Interactive Elixir (1.0.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> ManyProcessFactory.main

・・・・
send id=99974 key=a
send id=99989 key=a
[{:get, 'a', #PID<0.85.0>}, {:get, 'a', #PID<0.85.0>},

実行ができました。

# まとめ
今回の話は実際に実行してみた結果のみでの判断となりますが、Erlangにて+Pオプションはまだ有効となっている可能性が高いのかなっと思いました。
そのあたりもちゃんと追いかけていかないといけないなっと感じました。
以上、この記事が誰かの役に立てば幸いです。

それでは皆さま、良いElixirライフを