Class: DRb::DRbObject

Inherits:
Object
  • Object
show all
Defined in:
lib/drb/eq.rb,
lib/drb/gw.rb,
lib/drb/drb.rb

Overview

Object wrapping a reference to a remote drb object.

Method calls on this object are relayed to the remote object that this object is a stub for.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(obj, uri = nil) ⇒ DRbObject

Create a new remote object stub.

obj is the (local) object we want to create a stub for. Normally this is nil. uri is the URI of the remote object that this will be a stub for.



1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'lib/drb/drb.rb', line 1088

def initialize(obj, uri=nil)
  @uri = nil
  @ref = nil
  case obj
  when Object
    is_nil = obj.nil?
  when BasicObject
    is_nil = false
  end

  if is_nil
    return if uri.nil?
    @uri, option = DRbProtocol.uri_option(uri, DRb.config)
    @ref = DRbURIOption.new(option) unless option.nil?
  else
    @uri = uri ? uri : (DRb.uri rescue nil)
    @ref = obj ? DRb.to_id(obj) : nil
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(msg_id, *a, &b) ⇒ Object

Routes method calls to the referenced remote object.



1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
# File 'lib/drb/drb.rb', line 1134

def method_missing(msg_id, *a, &b)
  if DRb.here?(@uri)
    obj = DRb.to_obj(@ref)
    DRb.current_server.check_insecure_method(obj, msg_id)
    return obj.__send__(msg_id, *a, &b)
  end

  succ, result = self.class.with_friend(@uri) do
    DRbConn.open(@uri) do |conn|
      conn.send_message(self, msg_id, a, b)
    end
  end

  if succ
    return result
  elsif DRbUnknown === result
    raise result
  else
    bt = self.class.prepare_backtrace(@uri, result)
    result.set_backtrace(bt + caller)
    raise result
  end
end

Class Method Details

._load(s) ⇒ Object

Unmarshall a marshalled DRbObject.

If the referenced object is located within the local server, then the object itself is returned. Otherwise, a new DRbObject is created to act as a stub for the remote referenced object.



1050
1051
1052
1053
1054
1055
1056
1057
# File 'lib/drb/drb.rb', line 1050

def self._load(s)
  uri, ref = Marshal.load(s)
  if DRb.uri == uri
    return ref ? DRb.to_obj(ref) : DRb.front
  end

  self.new_with(DRb.uri, [:DRbObject, uri, ref])
end

.new_with(uri, ref) ⇒ Object

Creates a DRb::DRbObject given the reference information to the remote host uri and object ref.



1064
1065
1066
1067
1068
1069
# File 'lib/drb/drb.rb', line 1064

def self.new_with(uri, ref)
  it = self.allocate
  it.instance_variable_set(:@uri, uri)
  it.instance_variable_set(:@ref, ref)
  it
end

.new_with_uri(uri) ⇒ Object

Create a new DRbObject from a URI alone.



1072
1073
1074
# File 'lib/drb/drb.rb', line 1072

def self.new_with_uri(uri)
  self.new(nil, uri)
end

.prepare_backtrace(uri, result) ⇒ Object

Returns a modified backtrace from result with the uri where each call in the backtrace came from.



1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
# File 'lib/drb/drb.rb', line 1172

def self.prepare_backtrace(uri, result) # :nodoc:
  prefix = "(#{uri}) "
  bt = []
  result.backtrace.each do |x|
    break if /`__send__'$/ =~ x
    if /\A\(druby:\/\// =~ x
      bt.push(x)
    else
      bt.push(prefix + x)
    end
  end
  bt
end

.with_friend(uri) ⇒ Object

Given the uri of another host executes the block provided.



1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
# File 'lib/drb/drb.rb', line 1159

def self.with_friend(uri) # :nodoc:
  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

Instance Method Details

#==(other) ⇒ Object Also known as: eql?



4
5
6
7
# File 'lib/drb/eq.rb', line 4

def ==(other)
  return false unless DRbObject === other
 (@ref == other.__drbref) && (@uri == other.__drburi)
end

#__drbrefObject

Get the reference of the object, if local.



1114
1115
1116
# File 'lib/drb/drb.rb', line 1114

def __drbref
  @ref
end

#__drburiObject

Get the URI of the remote object.



1109
1110
1111
# File 'lib/drb/drb.rb', line 1109

def __drburi
  @uri
end

#_dump(lv) ⇒ Object

Marshall this object.

The URI and ref of the object are marshalled.



1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
# File 'lib/drb/drb.rb', line 1079

def _dump(lv)
  if DRb.uri == @uri
    if Array === @ref && @ref[0] == :DRbObject
      Marshal.dump([@ref[1], @ref[2]])
    else
      Marshal.dump([@uri, @ref]) # ??
    end
  else
    Marshal.dump([DRb.uri, [:DRbObject, @uri, @ref]])
  end
end

#hashObject



9
10
11
# File 'lib/drb/eq.rb', line 9

def hash
  [@uri, @ref].hash
end

#pretty_print(q) ⇒ Object

:nodoc:



1186
1187
1188
# File 'lib/drb/drb.rb', line 1186

def pretty_print(q)   # :nodoc:
  q.pp_object(self)
end

#pretty_print_cycle(q) ⇒ Object

:nodoc:



1190
1191
1192
1193
1194
1195
# File 'lib/drb/drb.rb', line 1190

def pretty_print_cycle(q)   # :nodoc:
  q.object_address_group(self) {
    q.breakable
    q.text '...'
  }
end

#respond_to?(msg_id, priv = false) ⇒ Boolean

Routes respond_to? to the referenced remote object.

Returns:

  • (Boolean)


1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
# File 'lib/drb/drb.rb', line 1122

def respond_to?(msg_id, priv=false)
  case msg_id
  when :_dump
    true
  when :marshal_dump
    false
  else
    method_missing(:respond_to?, msg_id, priv)
  end
end