忘れてたので自分用にまとめておく。
サーバ側:
require 'msgpack/rpc' class MyServer def ping_sync "pong" end def ping_async as = MessagePack::RPC::AsyncResult.new # as.result("pong") as.result("pong at #{Time.now}") return as end end mysvr = MyServer.new mpserver = MessagePack::RPC::Server.new mpserver.listen("127.0.0.1", 18888, mysvr) mpserver.run
同期呼び出しのときのテスト。
require 'msgpack/rpc' ret = nil mpclient = nil begin mpclient = MessagePack::RPC::Client.new("127.0.0.1", 18888) mpclient.timeout = 1 rescue # この時点でサーバがListenしていなかった場合、 # ここでTimeoutするように見える…が、実はそうでもない。ここではなにもraiseされてこない。 puts "caught: #{$!.inspect}" exit 1 end puts "--- call sync" begin puts "calling mpclient.call(:ping_sync)" ret = mpclient.call(:ping_sync) puts "ret: #{ret}" rescue # callしたときにサーバがListenしていないと、MessagePack::RPC::ConnectionTimeOut例外が上がる puts "caught: #{$!.inspect}" # -> caught: #<MessagePack::RPC::ConnectionTimeoutError: connection timed out> exit 1 end
非同期呼び出しのときのテスト。
require 'msgpack/rpc' ret = nil mpclient = nil begin mpclient = MessagePack::RPC::Client.new("127.0.0.1", 18888) mpclient.timeout = 10 rescue # この時点でサーバがListenしていなかった場合、 # ここでTimeoutするように見える…が、実はそうでもない。ここではなにもraiseされてこない。 puts "caught: #{$!.inspect}" exit 1 end future = nil begin puts "calling mpclient.call_async(:ping_async) at #{Time.now}" future = mpclient.call_async(:ping_async) # 返値はFutureクラス、この時点ではサーバ側では処理が行われない puts "future.class = #{future.class}" rescue # call_asyncした時点でサーバがListenしていない場合でも、ここではなにもraiseされてこない。 puts "caught: #{$!.inspect}" end puts "sleeping for 5 sec." sleep 5 begin puts "-> calling Future.get" ret = future.get puts "ret = #{ret} / Time.now=#{Time.now}" puts "future.class = #{future.class}" puts "ret.class = #{ret.class}" rescue # ここで初めてping_asyncの処理が走る。サーバがListenしていない場合には例外が上がる puts "caught: #{$!.inspect}" # 最初からサーバがListenしていなかった場合: # -> caught: #<MessagePack::RPC::ConnectionTimeoutError: connection timed out> # 最初はサーバがListenしていたが、処理中に時間がかかりすぎてタイムアウトした場合: # -> caught: #<MessagePack::RPC::TimeoutError: request timed out> exit 1 end
asyncの実行結果:
calling mpclient.call_async(:ping_async) at 2011-11-08 16:49:00 +0900 # call_asyncを呼んだのは16:49:00 future.class = MessagePack::RPC::Future sleeping for 5 sec. -> calling Future.get ret = pong at 2011-11-08 16:49:05 +0900 / Time.now=2011-11-08 16:49:05 +0900 # サーバ側でping_asyncが呼ばれたのは16:49:05 future.class = MessagePack::RPC::Future ret.class = String
要約:
- Client.newした時点でサーバがListenしていなくても例外は上がらない
- call, call_asyncした時点でサーバがListenしていないとMessagePack::RPC::ConnectionTimeoutErrorが上がる
- call, call_asyncしてサーバが処理をしているとき、時間がかかりすぎてタイムアウトした場合にはMessagePack::RPC::TimeoutErrorが上がる
- call_async(:remote_func, args) で呼び出したとしても、サーバ側ではまだremote_funcは呼び出されない。返値のfutureに対してgetを呼ぶと初めて実行が行われる