diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | lib/drb/drb.rb | 91 | ||||
-rw-r--r-- | lib/drb/gw.rb | 74 |
3 files changed, 141 insertions, 33 deletions
@@ -1,3 +1,12 @@ +Mon Mar 28 23:40:40 2005 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp> + + * lib/drb/drb.rb: move method DRbObject#reinit to DRbObject.new_with. + extract method DRbObject.prepare_backtrace. add DRb.regist_server, + remove_server, fetch_server. change server in thread variable if + in-proc sesrver. [druby-ja:113] + + * lib/drb/gw.rb: ditto. + Mon Mar 28 20:43:34 2005 Nobuyoshi Nakada <nobu@ruby-lang.org> * ext/syck/rubyext.c: get rid of warnings caused by a bug of VC. diff --git a/lib/drb/drb.rb b/lib/drb/drb.rb index 8eec4a7f1c..d40b6b3721 100644 --- a/lib/drb/drb.rb +++ b/lib/drb/drb.rb @@ -992,8 +992,13 @@ module DRb return DRb.to_obj(ref) end - it = self.new(nil) - it.reinit(uri, ref) + self.new_with(uri, ref) + end + + def self.new_with(uri, ref) + it = self.allocate + it.instance_variable_set('@uri', uri) + it.instance_variable_set('@ref', ref) it end @@ -1027,12 +1032,6 @@ module DRb end end - # Reinitialise this object with the given +uri+ and +ref+ - def reinit(uri, ref) - @uri = uri - @ref = ref - end - # Get the URI of the remote object. def __drburi @uri @@ -1065,25 +1064,45 @@ module DRb return obj.__send__(msg_id, *a, &b) end - succ, result = DRbConn.open(@uri) do |conn| - conn.send_message(self, msg_id, a, b) + succ, result = self.class.with_friend(@uri) do + DRbConn.open(@uri) do |conn| + conn.send_message(self, msg_id, a, b) + end end - return result if succ - unless DRbUnknown === result - prefix = "(#{@uri}) " - bt = [] - result.backtrace.each do |x| - break if /`__send__'$/ =~ x - if /^\(druby:\/\// =~ x - bt.push(x) - else - bt.push(prefix + x) - end - end - raise result, result.message, bt + caller + + if succ + return result + elsif DRbUnknown === result + raise result else - raise result + bt = self.class.prepare_backtrace(@uri, result) + raise result, result.message, bt + caller + end + end + + def self.with_friend(uri) + friend = DRb.fetch_server(uri) + return yield() unless friend + + save = Thread.current['DRb'] + Thread.current['DRb'] = { 'server' => friend } + return yield + ensure + Thread.current['DRb'] = save if friend + end + + def self.prepare_backtrace(uri, result) + prefix = "(#{uri}) " + bt = [] + result.backtrace.each do |x| + break if /`__send__'$/ =~ x + if /^\(druby:\/\// =~ x + bt.push(x) + else + bt.push(prefix + x) + end end + bt end def pretty_print(q) # :nodoc: @@ -1309,9 +1328,7 @@ module DRb @grp = ThreadGroup.new @thread = run - Thread.exclusive do - DRb.primary_server = self unless DRb.primary_server - end + DRb.regist_server(self) end # The URI of this DRbServer. @@ -1352,6 +1369,7 @@ module DRb # Stop this server. def stop_service + DRb.remove_server(self) if Thread.current['DRb'] && Thread.current['DRb']['server'] == self Thread.current['DRb']['stop_service'] = true else @@ -1702,6 +1720,25 @@ module DRb DRbServer.default_acl(acl) end module_function :install_acl + + @server = {} + def regist_server(server) + @server[server.uri] = server + Thread.exclusive do + @primary_server = server unless @primary_server + end + end + module_function :regist_server + + def remove_server(server) + @server.delete(server.uri) + end + module_function :remove_server + + def fetch_server(uri) + @server[uri] + end + module_function :fetch_server end DRbObject = DRb::DRbObject diff --git a/lib/drb/gw.rb b/lib/drb/gw.rb index 012a2b0a11..b7a5f5383f 100644 --- a/lib/drb/gw.rb +++ b/lib/drb/gw.rb @@ -5,9 +5,7 @@ module DRb class GWIdConv < DRbIdConv def to_obj(ref) if Array === ref && ref[0] == :DRbObject - it = DRbObject.new(nil) - it.reinit(ref[1], ref[2]) - return it + return DRbObject.new_with(ref[1], ref[2]) end super(ref) end @@ -40,9 +38,7 @@ module DRb return ref ? DRb.to_obj(ref) : DRb.front end - it = self.new(nil) - it.reinit(DRb.uri, [:DRbObject, uri, ref]) - it + self.new_with(DRb.uri, [:DRbObject, uri, ref]) end def _dump(lv) @@ -58,3 +54,69 @@ module DRb end end end + +=begin +DRb.install_id_conv(DRb::GWIdConv.new) + +front = DRb::GW.new + +s1 = DRb::DRbServer.new('drbunix:/tmp/gw_b_a', front) +s2 = DRb::DRbServer.new('drbunix:/tmp/gw_b_c', front) + +s1.thread.join +s2.thread.join +=end + +=begin +# foo.rb + +require 'drb/drb' + +class Foo + include DRbUndumped + def initialize(name, peer=nil) + @name = name + @peer = peer + end + + def ping(obj) + puts "#{@name}: ping: #{obj.inspect}" + @peer.ping(self) if @peer + end +end +=end + +=begin +# gw_a.rb +require 'drb/unix' +require 'foo' + +obj = Foo.new('a') +DRb.start_service("drbunix:/tmp/gw_a", obj) + +robj = DRbObject.new_with_uri('drbunix:/tmp/gw_b_a') +robj[:a] = obj + +DRb.thread.join +=end + +=begin +# gw_c.rb +require 'drb/unix' +require 'foo' + +foo = Foo.new('c', nil) + +DRb.start_service("drbunix:/tmp/gw_c", nil) + +robj = DRbObject.new_with_uri("drbunix:/tmp/gw_b_c") + +puts "c->b" +a = robj[:a] +sleep 2 + +a.ping(foo) + +DRb.thread.join +=end + |