IronRuby と MRI の連携を考えてみる。
ruby には dRuby と呼ばれるライブラリがある。サイトを見ると以下のような記載がある
dRubyはRubyのメソッド呼び出しを拡張し、ネットワーク越しにメソッド呼び出しを行なえるようにするライブラリです。 JavaのRMIやHORBをイメージすると近いです。
また、100% pure ruby な実装とのことです
今回は、この dRuby を用いて、プロセス間通信をしてみる。
ただのプロセス間通信であるならば、あまり面白くない。
そこで、片方をIronRuby、別をMRI上の動作を目指してみようと思う。
ソース
本来の dRuby 流儀からすると外れている設計パターンかもしれないが、以下のソースを利用する。なお、実験用であるために、かなり手を抜いている。
サーバ側
require 'drb/drb'
require 'thread'
class Server
def initialize( queue )
@queue = queue
Thread.new do
message_loop
end
end
def message_loop
loop do
a = @queue.dequeue
p a
request , params = *a
p [request , params]
end
end
end
class RequestQueue
def initialize
@q = Queue.new
end
def add_request( request , params )
@q.push( [ request , params ] )
end
def dequeue
@q.pop
end
end
request_queue = RequestQueue.new
server = Server.new( request_queue )
DRb.start_service('druby://127.0.0.1:1495',request_queue)
puts DRb.uri
DRb.thread.join
クライアント側
require 'drb/drb' url = ARGV[0] p url q = DRbObject.new_with_uri(url) q.add_request( :func1 , [12,34] )
簡単に記載すると、クライアントとサーバ間にメッセージ用のキューを生成する。このキューにクライアントが機能を識別するシンボルとそのパラメータを詰める。このキューはdrubyによって共有されており、クライアントがキューに詰めたアイテムはサーバ側に伝わることとなる。サーバ側はそのキューにアイテムが詰め込まれるまで待ち、そのアイテムを処理する。当然サーバ側はこの処理をループで処理するが、キューによって直列処理に代えられている。
動作
実際の動作をすると、以下のようになる。
サーバ側
C:\work>\ruby-1.8.7-p72-i386-mswin32\bin\ruby.exe druby\server.rb druby://127.0.0.1:1495 [:func1, [12, 34]] [:func1, [12, 34]]
クライアント側
C:\work>\ruby-1.8.7-p72-i386-mswin32\bin\ruby.exe druby\client.rb druby://127.0.0.1:1495 "druby://127.0.0.1:1495"
クライアント側にサーバ側のURIを指定し実行するとメッセージが送信されその処理が行われる。実際にはサーバ側は表示するだけである。なお、今回は2度表示されているが、意図した動きである。
IronRuby 0.9.1
さて、上記のクライアントをIronRuby 0.9.1 で動作させてみた。サーバ側は先ほどと同じサーバをそのまま使用する。
クライアント側
C:\work>\ironruby-0.9.1\bin\ir.exe druby\client.rb druby://127.0.0.1:1495
"druby://127.0.0.1:1495"
C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:581:in `load': undefined method `exclusive' for Thread:Class (NoMethodError)
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:632:in `recv_reply'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:921:in `recv_reply'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1195:in `send_message'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1086:in `method_missing'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1170:in `open'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1085:in `method_missing'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1102:in `with_friend'
from C:/ironruby-0.9.1/lib/ruby/1.8/drb/drb.rb:1084:in `method_missing'
from druby/client.rb:6
サーバ側に正しくデータが来ているようであるが、クライアント側でエラーが出てしまっている。
MRIのThreadにはexclusiveがクラスメソッドとしてあるが、IronRubyにはないためにエラーがでているようである。
調べてみると 0.9.1では実装されていないようである。また調査中に 0.9.2 がリリースされていたのでダウンロードして試してみた。
IronRuby 0.9.2
クライアント側
C:\work>\ironruby-0.9.2\bin\ir.exe druby\client.rb druby://127.0.0.1:1495 "druby://127.0.0.1:1495"
無事例外も発生せず終了。サーバ側のコンソールには、以下のように3回分(6行)表示されていた。なお、MRI同士、IronRuby0.9.1、IronRuby0.9.2の3回である
サーバ側
C:\work>\ruby-1.8.7-p72-i386-mswin32\bin\ruby.exe druby\server.rb druby://127.0.0.1:1495 [:func1, [12, 34]] [:func1, [12, 34]] [:func1, [12, 34]] [:func1, [12, 34]] [:func1, [12, 34]] [:func1, [12, 34]]
なお、IronRuby0.9.2のリリースノートによると
(sborde) Implements Thread.exclusive. Enables a minimal test for Shell which was blocked on Thread.exclusive
との事らしい
まとめ
IronRubyとMRIの連携がまかりなりにも動作することが分かった。これでかなり夢が広がると考えられる。まだIronRubyとして弱い部分を MRI に任せるなどが出来ることや、あるいは Unix(MRI)とWindows(IronRuby)の連携等も考えられる。


コメントする