Class: DRb::DRbObject

Inherits:
Object
  • Object
show all
Defined in:
lib/drb/gw.rb,
lib/drb/eq.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.


1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
# File 'lib/drb/drb.rb', line 1094

def initialize(obj, uri=nil)
  @uri = nil
  @ref = nil
  if obj.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.


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

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.


1053
1054
1055
1056
1057
1058
1059
1060
# File 'lib/drb/drb.rb', line 1053

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.


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

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.


1078
1079
1080
# File 'lib/drb/drb.rb', line 1078

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.


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

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

.with_friend(uri) ⇒ Object

Given the uri of another host executes the block provided.


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

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.


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

def __drbref
  @ref
end

#__drburiObject

Get the URI of the remote object.


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

def __drburi
  @uri
end

#_dump(lv) ⇒ Object

Marshall this object.

The URI and ref of the object are marshalled.


1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
# File 'lib/drb/drb.rb', line 1085

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:


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

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

#pretty_print_cycle(q) ⇒ Object

:nodoc:


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

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)

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

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