diff options
author | seki <seki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-18 15:45:12 +0000 |
---|---|---|
committer | seki <seki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-06-18 15:45:12 +0000 |
commit | 151f1241c665b0307234e931bec2c32bfea0138d (patch) | |
tree | 6ca5c5e535d66aaf094e954446846955f2e18a88 /lib/drb/timeridconv.rb | |
parent | 34cdb70d14ea1fdddf3f3991f6097fe5c24310ba (diff) |
import from drb-2.0.4b3
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3959 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/drb/timeridconv.rb')
-rw-r--r-- | lib/drb/timeridconv.rb | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/drb/timeridconv.rb b/lib/drb/timeridconv.rb new file mode 100644 index 0000000000..bb2c48d528 --- /dev/null +++ b/lib/drb/timeridconv.rb @@ -0,0 +1,91 @@ +require 'drb/drb' +require 'monitor' + +module DRb + class TimerIdConv < DRbIdConv + class TimerHolder2 + include MonitorMixin + + class InvalidIndexError < RuntimeError; end + + def initialize(timeout=600) + super() + @sentinel = Object.new + @gc = {} + @curr = {} + @renew = {} + @timeout = timeout + @keeper = keeper + end + + def add(obj) + synchronize do + key = obj.__id__ + @curr[key] = obj + return key + end + end + + def fetch(key, dv=@sentinel) + synchronize do + obj = peek(key) + if obj == @sentinel + return dv unless dv == @sentinel + raise InvalidIndexError + end + @renew[key] = obj # KeepIt + return obj + end + end + + def include?(key) + synchronize do + obj = peek(key) + return false if obj == @sentinel + true + end + end + + def peek(key) + synchronize do + return @curr.fetch(key, @renew.fetch(key, @gc.fetch(key, @sentinel))) + end + end + + private + def alternate + synchronize do + @gc = @curr # GCed + @curr = @renew + @renew = {} + end + end + + def keeper + Thread.new do + loop do + size = alternate + sleep(@timeout) + end + end + end + end + + def initialize(timeout=600) + @holder = TimerHolder2.new(timeout) + end + + def to_obj(ref) + return super if ref.nil? + @holder.fetch(ref) + rescue TimerHolder2::InvalidIndexError + raise "invalid reference" + end + + def to_id(obj) + return @holder.add(obj) + end + end +end + +# DRb.install_id_conv(TimerIdConv.new) |