perl erlang プロセス間で直接メッセージを送受信する
単純に erl_interface を Inline::C から使っただけなんですが(w;
erlang 側の準備
特別な準備は無し。
とりあえず、送受信するプロセスを適当に作っておく。
-module(pingpong). -compile(export_all). start() -> register(pingpong, spawn(?MODULE, loop, [])). stop() -> pingpong ! stop. loop() -> receive stop -> io:fwrite("~w:stop.~n", [self()]), exit(ok); {message, Pid, Message} -> io:fwrite("Pid:~w~nMessage:~s~n", [Pid, Message]), Pid ! {message, self(), "pong"}; Other -> io:fwrite("Other:~w~n", [Other]) end, loop().
% erlc pingpong.erl % erl -name test@`hostname` -s pingpong start
perl 側の準備
http://labs.miu.vc/svn/cooldaemon/perl/Erlang-Interface/lib を任意の場所に設置。
lib/Erlang/Interface/InlineC.pm の下記の LIBS と INC を適切なパスに書き換える。
use Inline C => Config ## no critic => CCFLAGS => '-std=c99' => LIBS => '-L/opt/local/lib/erlang/lib/erl_interface-3.5.5.3/lib -lerl_interface -lei' => INC => '-I/opt/local/lib/erlang/lib/erl_interface-3.5.5.3/include';
erlang プロセスとメッセージを送受信するスクリプトを書く。
#!/usr/bin/env perl use strict; use warnings; use feature qw(:5.10); use version; our $VERSION = qv('0.0.1'); use Carp; use English qw(-no_match_vars); use Erlang::Interface; my $eif = Erlang::Interface->new; say $eif->node(); my $fd = $eif->connect(alive => 'test'); my $atom = Erlang::Interface::Eterm->make_atom('message'); my $string = Erlang::Interface::Eterm->make_string('ping'); my $pid = $fd->self_pid; my $tuple = Erlang::Interface::Eterm->make_tuple($atom, $pid, $string,); $fd->reg_send('pingpong', $tuple) or croak 'send error.'; my $recv = $fd->receive() or croak 'receive error.'; if ($recv->is_tuple) { for ($recv->value) { if ($_->is_pid) { $fd->send($_, $tuple) or croak 'send error'; next; } say $_->value; } }
試す
% perl pingpong.pl A9D28758-DAC7-11DC-89C1-DF2240E9B49D@xxxxxx.jp message pong
今後
rpc を実装する。
対応した
my $string = Erlang::Interface::Eterm->make_string('hello!!'); my $args = Erlang::Interface::Eterm->make_list($string); my $recv0 = $fd->rpc('io', 'fwrite', $args) or croak 'rpc error.'; say $recv->value; $fd->rpc_send('io', 'fwrite', $args) or croak 'rpc_send error.'; my $recv1 = $fd->rpc_receive() or croak 'rpc_receive error.'; say $recv1->value;
Global Names に対応する。