l'essentiel est invisible pour les yeux

Monday, May 21, 2007

[Ruby and Erlang] そろそろRBridge::Erlangについて一言いっておくか

RBridge::Erlang


を作った。

弾さんもErlangについて一言言うなどここ最近のErlangの盛り上がりは凄い。

Erlangを1週間ほどさわってみて思ったのは次の二つ。
  • Erlangの軽量なプロセスをRubyから扱いたい。
  • Erlang/OTPが実績もありすばらしい(そう)なのでRubyからその恩恵にあずかる


とりあえず、はじめてのErlanモジュール作成ということで悩んだ結果、RubyからErlangのメソッドを呼び出すRBridge::Erlangを作った。現在同期呼び出しのみサポートしている。ErlangとRuby間の通信におけるプロトコルはJSON-RPCである。


ダウンロード
rbridge-0.0.1.tar.gz

デモの動かし方。
コンパイル

% tar xvzf rbridge-0.0.1.tar.gz
% cd rbridge-0.0.1.tar.gz
% make


Erlang側のサーバを起動する。

% erl
1> c(geometry).
2> geometry:start().


後は、Ruby側から呼び出すだけ。

require 'rbridge'
geo = RBridge::Erlang.new(:geometry, "127.0.0.1")
geo.area({:x => 100, :y => 200}) # => 20000

ポートの変更
デフォルトのポートは3793番を使用しているので、使用している際は次のファイルのPortの設定を変更してください。その際は、Ruby側のRBridge::Erlang.newの第三引数に指定したポートを渡す必要あり。

% cat server_root/conf/httpd.conf
ServerName localhost
ServerRoot server_root
DocumentRoot server_root/htdocs
Port 3793
Modules mod_alias mod_auth mod_jsonrpc mod_actions mod_cgi mod_responsecontrol mod_trace mod_range mod_head mod_include mod_dir mod_get mod_log mod_disk_log
DirectoryIndex index.html
JsonRpcAlias /rpc
ErrorLog logs/error_log
TransferLog logs/access_log
SecurityLog logs/security_log


Erlang側のソース
関数を定義して、rbridge:start関数の引数にリストで渡すだけ。
rbridge:startの第一引数はお約束。?MODULE(現在のモジュール名)を渡してください。
第二引数にservice_procレコードのリストを渡す。idempotent=true or falseはGETリクエストによるJSON-RPCを受け付けるかどうか。POSTは現在実装していないのでtrueにしてください。paramsはサービスの引数を定義する。引数のキーの名前と型("bit" | "num" | "str" | "arr" | "obj" | "any" | nil)のいずれかを指定します。


-module(geometry).
-export([area/2, start/0, stop/0]).

-include("include/rbridge.hrl").

%% Get area
area(X, Y) when is_number(X), is_number(Y) ->
X * Y.

%% service_proc#type ::= "bit" | "num" | "str" | "arr" | "obj" | "any" | nil
start() ->
rbridge:start(?MODULE,
[#service_proc{name = <<"area">>,
idempotent=true,
params=[#service_proc_param{name = <<"x">>, type = <<"num">>},
#service_proc_param{name = <<"y">>, type = <<"num">>}]}]).

% Stop RBrige server
stop() ->
rbridge:stop().



TODO:
「RubyからErlang/OTPの恩恵をどうやって授かるか?」について色々と考えてみる。


追記
id:sfujiwaraさんがPerlから呼び出すコードを書いてくれています。
[Perl][Erlang] RBridge::Erlang を Perl から呼ぶ