Hello, dRuby
特に利用目的はありませんがdRuby触ってみます。
単に1台のマシン上で動かすのでは面白くないので、C RubyとJRubyの間でのプロセス間通信も試してみます。
動作環境
サーバ側スクリプト
今回はCRubyで動かしています。単純にハッシュに対する値の出し入れをするだけのものです。
store.rb
require 'drb/drb' class Store def initialize @hash = {} end def put(key, value) @hash[key] = value end def get(key) @hash[key] end def keys @hash.keys end end uri = ARGV.shift DRb.start_service("druby://:10080", Store.new) puts "service started." sleep
実行結果:
% ruby store.rb service started.
クライアント (CRubyその1)
IRBから、先ほどのリモートオブジェクトを指すDRbObjectオブジェクトを作成します。当然通常のRubyオブジェクトと同様に読み書きできています。
% irb -rdrb/drb > irb -rdrb/drb irb(main):001:0> remote = DRbObject.new_with_uri('druby://localhost:10080') => #<Store:0x842568c> irb(main):002:0> remote.put('hello', 'world') => "world" irb(main):003:0> remote.get('hello') => "world"
クライアント (JRuby)
次に、JRubyのIRBから、先ほどのリモートオブジェクトの値を参照します。先ほどCRubyクライアント経由で書き込んだ値が反映されていること (→リモートオブジェクトの実体はサーバ側にあること) が確認できます。
さらに、新規のキーをリモートオブジェクトに追加します。
% jirb -rdrb/drb irb(main):001:0> remote = DRbObject.new_with_uri("druby://localhost:10080") => #<DRb::DRbObject:0x1a80aea @uri="druby://localhost:10080", @ref=nil> irb(main):002:0> remote.get("hello") => "world" irb(main):003:0> remote.put("merry", "christmas") => "christmas" irb(main):004:0> remote.get("merry") => "christmas"
クライアント (CRubyその2)
最後に、先ほどのCRuby側IRBクライアントから、JRuby側でセットしたキーが見えることを確認します。
irb(main):004:0> remote.get("merry") => "christmas" irb(main):005:0> remote.keys => ["hello", "merry"]
メモ
環境依存の問題と思われますが、サーバ側: CRuby、クライアント側: JRubyの組み合わせで、DRb.start_serviceの引数を "druby//:10080" の代わりに "druby://localhost:10080" とすると、クライアントからうまく接続できないという現象が発生しました。
% jirb -rdrb/drb irb(main):001:0> remote = DRbObject.new_with_uri("druby://localhost:10080") => #<DRb::DRbObject:0x164b9b6 @uri="druby://localhost:10080", @ref=nil> irb(main):002:0> remote.keys DRb::DRbConnError: druby://localhost:10080 - #<Errno::ECONNREFUSED: Connection refused - Connection refused>
おそらくJRubyでlocalhostを指定したときにループバックインタフェースではなくeth0に接続しに行っていると推測しましたが、それ以上は追跡していません。