Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 35 additions & 7 deletions lib/drb/drb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,39 @@ class DRbError < RuntimeError; end
# protocol.
class DRbConnError < DRbError; end

class DRbObjectSpace # :nodoc:
# This is an internal class for DRbIdConv. This must not be used
# by users.

include MonitorMixin

def initialize
super()
@map = ObjectSpace::WeakMap.new
end

def to_id(obj)
synchronize do
@map[obj.__id__] = obj
obj.__id__
end
end

def to_obj(ref)
synchronize do
obj = @map[ref]
raise RangeError.new("invalid reference") unless obj.__id__ == ref
obj
end
end
end

# :nodoc:
#
# This is an internal singleton instance. This must not be used
# by users.
DRB_OBJECT_SPACE = DRbObjectSpace.new

# Class responsible for converting between an object and its id.
#
# This, the default implementation, uses an object's local ObjectSpace
Expand All @@ -364,20 +397,15 @@ class DRbIdConv
# This implementation looks up the reference id in the local object
# space and returns the object it refers to.
def to_obj(ref)
ObjectSpace._id2ref(ref)
DRB_OBJECT_SPACE.to_obj(ref)
end

# Convert an object into a reference id.
#
# This implementation returns the object's __id__ in the local
# object space.
def to_id(obj)
case obj
when Object
obj.nil? ? nil : obj.__id__
when BasicObject
obj.__id__
end
(nil == obj) ? nil : DRB_OBJECT_SPACE.to_id(obj)
end
end

Expand Down
62 changes: 17 additions & 45 deletions lib/drb/weakidconv.rb
Original file line number Diff line number Diff line change
@@ -1,57 +1,29 @@
# frozen_string_literal: false
require_relative 'drb'
require 'monitor'

module DRb

# DRb::WeakIdConv is deprecated since 2.2.1. You don't need to use
# DRb::WeakIdConv instead of DRb::DRbIdConv. It's the same class.
#
# This file still exists for backward compatibility.
#
# 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)
def self.const_missing(name) # :nodoc:
case name
when :WeakIdConv
warn("DRb::WeakIdConv is deprecated. " +
"You can use the DRb::DRbIdConv. " +
"You don't need to use this.",
uplevel: 1)
const_set(:WeakIdConv, DRbIdConv)
singleton_class.remove_method(:const_missing)
DRbIdConv
else
super
end
end
end
Expand Down
4 changes: 3 additions & 1 deletion test/drb/test_drbobject.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'test/unit'
require 'envutil'
require 'drb'
require 'drb/timeridconv'
require 'drb/weakidconv'
Expand Down Expand Up @@ -64,6 +65,7 @@ class TestDRbObjectWeakIdConv < Test::Unit::TestCase
include DRbObjectTest

def setup
DRb.start_service(nil, nil, {:idconv => DRb::WeakIdConv.new})
idconv = EnvUtil.suppress_warning {DRb::WeakIdConv.new}
DRb.start_service(nil, nil, {:idconv => idconv})
end
end