IronRuby と MRIの連携(dRuby)編 -連続要求発行-

| コメント(0) | トラックバック(0) このエントリーを含むはてなブックマーク

IronRuby と MRIの連携(dRuby)で通信が出来るということは確認した。しかし、安定していないと当然使い物にならない。
この辺を確認するために、今回調べてみようと思う。

連続耐久試験

当然、安定して動作しないと使えないということで、たくさんの要求を出してみる検証を行った。

修正ソース

require 'drb/drb' 
url = ARGV[0]
p url
q = DRbObject.new_with_uri(url) 

1000.times do 
  q.add_request( :func1 , [12,34] )
end

結果

C:\work>\ironruby-0.9.2\bin\ir.exe druby\client_2.rb druby://127.0.0.1:1495
"druby://127.0.0.1:1495"
C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:580:in `load': premature marshal format(can't read) (DRb::DRbConnError)
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:633:in `recv_reply'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:921:in `recv_reply'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1195:in `send_message'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1086:in `method_missing'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1170:in `open'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1085:in `method_missing'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1102:in `with_friend'
        from C:/ironruby-0.9.2/lib/ruby/1.8/drb/drb.rb:1084:in `method_missing'
        from druby/client_2.rb:8
        from druby/client_2.rb:7
        from :0:in `times'
 
 

5回目くらいの要求発行で例外発生!?えっ!えっ!該当部分のソースをみてみると

begin
  str = soc.read(sz)
rescue
  raise(DRbConnError, $!.message, $!.backtrace)
end
raise(DRbConnError, 'connection closed') if str.nil?
raise(DRbConnError, 'premature marshal format(can\'t read)') if str.size < sz


一番下の部分で例外が出ている。つまり、読み込んだサイズと読み込まれるべきサイズの差があるようだ。

基礎実験開始

サーバ側ソース

require "socket"

gs = TCPServer.open('127.0.0.1',12345)
socks = [gs]
addr = gs.addr
addr.shift
printf("server is on %s\n", addr.join(":"))

loop do
  nsock = select(socks)
  next if nsock == nil
  for s in nsock[0]
    if s == gs
      socks.push(s.accept)
      print(s, " is accepted\n")
    else
      if s.eof?
        print(s, " is gone\n")
        s.close
        socks.delete(s)
      else
        ls = s.read(4)
p ls.size
        num = ls.unpack("I")
p num
        str = s.read(num[0])
p str.size
p        s.write(str*20)
      end
    end
  end
end


クライアント側ソース

require "socket"

s = TCPSocket.open("127.0.0.1", 12345)

c='a'
100000.times do |i|
  num = rand(1000)+1
  c = '%c' % ("0123456789"[i%10])
  wr4 = s.write([num].pack('I'))
  wrn = s.write(c*num)
  r = s.read(num*20)
  puts "#{(num*20 == r.size).inspect}\t#{c} #{r[0]} #{r[1]} #{num} #{r.size} #{wr4}(4) #{wrn}"
  exit unless num*20 == r.size
end
s.close


MRI および IronRuby 0.9.2 で動作するぞ。

最初 socke.read( request_size ) の request_size 指定分読み込めないのかと思った。 rubyのsocket.read は指定されたサイズ到着までブロックするはずであり、ブロック抜けてきたという事は、そのサイズ分到着したということである。その到着したはずなのに差があるということで例外が出ているのかと思い、上記の基本プログラムで動作を確認した。

そうしたところ、その挙動をしている。IronRuby 0.9.2 の バグかと思っていたが、そうではなさそうだ

IronRuby と MRI 間通信

試しに、先ほどの druby通信のクライアント側を IronRuby 0.9.2 / サーバ側を ruby 1.8.7 で行ったところ、無事通信ができている

またdruby通信のクライアント側を ruby 1.8.7 / サーバ側を IronRuby 0.9.2で行ったところ、無事通信ができている

これはまた謎が深まってきた

まとめ

これをまとめると、何らかのタイミングなどを含むバグがあるみたいである。この辺を解明しないと、昼もぐっすり眠れないかもしれない。

トラックバック(0)

トラックバックURL: http://www.m-tea.info/mt-tb.cgi/16

コメントする

あわせて読みたいブログパーツ

このブログ記事について

このページは、k1ha410が2009年11月15日 17:49に書いたブログ記事です。

ひとつ前のブログ記事は「書籍購入」です。

次のブログ記事は「IronRuby と MRIの連携(dRuby)編 -連続要求発行不具合調査編-」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。