зеркало из https://github.com/github/ruby.git
add DRb::WeakIdConv (Bug #15711)
This commit is contained in:
Родитель
b72623012d
Коммит
8980b53a48
|
@ -0,0 +1,59 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative 'drb'
|
||||
require 'monitor'
|
||||
|
||||
module DRb
|
||||
|
||||
# To use WeakIdConv:
|
||||
#
|
||||
# DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
|
||||
|
||||
class WeakIdConv < DRbIdConv
|
||||
class WeakSet
|
||||
include MonitorMixin
|
||||
def initialize
|
||||
super()
|
||||
@immutable = {}
|
||||
@map = ObjectSpace::WeakMap.new
|
||||
end
|
||||
|
||||
def add(obj)
|
||||
synchronize do
|
||||
begin
|
||||
@map[obj] = self
|
||||
rescue ArgumentError
|
||||
@immutable[obj.__id__] = obj
|
||||
end
|
||||
return obj.__id__
|
||||
end
|
||||
end
|
||||
|
||||
def fetch(ref)
|
||||
synchronize do
|
||||
@immutable.fetch(ref) {
|
||||
@map.each { |key, _|
|
||||
return key if key.__id__ == ref
|
||||
}
|
||||
raise RangeError.new("invalid reference")
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize()
|
||||
super()
|
||||
@weak_set = WeakSet.new
|
||||
end
|
||||
|
||||
def to_obj(ref) # :nodoc:
|
||||
return super if ref.nil?
|
||||
@weak_set.fetch(ref)
|
||||
end
|
||||
|
||||
def to_id(obj) # :nodoc:
|
||||
return @weak_set.add(obj)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DRb.install_id_conv(WeakIdConv.new)
|
|
@ -1,6 +1,7 @@
|
|||
require 'test/unit'
|
||||
require 'drb'
|
||||
require 'drb/timeridconv'
|
||||
require 'drb/weakidconv'
|
||||
|
||||
module DRbObjectTest
|
||||
class Foo
|
||||
|
@ -45,3 +46,19 @@ class TestDRbObjectTimerIdConv < Test::Unit::TestCase
|
|||
DRb.start_service(nil, nil, {:idconv => DRb::TimerIdConv.new})
|
||||
end
|
||||
end
|
||||
|
||||
class TestDRbObjectWeakIdConv < Test::Unit::TestCase
|
||||
include DRbObjectTest
|
||||
|
||||
def setup
|
||||
DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
|
||||
end
|
||||
|
||||
def test_RangeError
|
||||
proxy = DRbObject.new("string".dup)
|
||||
GC.start
|
||||
assert_raise(RangeError) {
|
||||
DRb.to_obj(proxy.__drbref)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче