今回は、以前のお話で出てきた ruby用のマルチスレッド対応キューと dRubyを用いて作成する部分について書いてみようと思う。
キューの仕掛けを使わなくてもいいかもしれないが、キューの話なのであえてdrubyとキューベースの記述をしている
dRubyについて
drubyは、説明によると、以下のようにある。
dRubyはRubyのメソッド呼び出しを拡張し、ネットワーク越しにメソッド呼び出しを行なえるようにするライブラリです。 JavaのRMIやHORBをイメージすると近いです。
という事で、ネットワーク越しに、当然プロセス越しにメソッド呼び出しが行える。
最初出合った頃は、右の書籍が出ていた。最近は左の書籍が出ているそうなので、そちらを参考にするといいかも。
dDubyの考え方
dRuby は サーバとクライアントのように分けることが出来る。厳密に分けないといけないかどうかは悩むが、今回は分ける。
シンプルなサーバ
サーバ側で以下のようなコードを書く
require 'drb/drb'
class Front
def func
puts "hello world"
end
end
front = Front.new
DRb.start_service('druby://127.0.0.1:1495',front)
puts DRb.uri
DRb.thread.join
シンプルなクライアント
クライアント側は以下のようなコードを書く
require 'drb/drb' url = 'druby://127.0.0.1:1495' obj = DRbObject.new_with_uri(url) obj.func()
このコードを実行すると、サーバ側の端末に hello world と表示される。以下のような動作が行われてたと理解していい。
プロセスを超えてサーバ側で生成されたオブジェクトの参照がクライアントへ渡りクライアントから参照への要求が行われるとサーバ側に伝わり処理される。
キューとの連携
サーバ側でキューと連携をする事を考えてみる
サーバとクライアント
サーバを以下のように作り
require 'drb/drb'
require 'thread'
q = Queue.new
DRb.start_service('druby://127.0.0.1:1495',q)
puts DRb.uri
DRb.thread.join
クライアントを以下のように作る
require 'drb/drb' url = 'druby://127.0.0.1:1495' obj = DRbObject.new_with_uri(url) obj.enq(item)
上記は以下のようになる。
サーバでキューを処理する
サーバを以下のように作り
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.deq
request , params = *a
p [request , params]
#ここでリクエストを処理する
end
end
end
q = Queue.new
server = Server.new( q )
DRb.start_service('druby://127.0.0.1:1495',q)
puts DRb.uri
DRb.thread.join
クライアントを以下のように作る
require 'drb/drb' url = 'druby://127.0.0.1:1495' obj = DRbObject.new_with_uri(url) obj.enq([:func_name,[1,2,3]])
このようにすると、クライアント側からの要求をネットワーク越し、プロセス越しに渡すことができる。
なお、サーバ側のメッセージを処理する部分は、シングルスレッドで動作している。
まとめ
drubyを使えば、簡単にネットワーク間、プロセス間でメッセージのやり取りが出来る。





コメントする