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.



1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
# File 'lib/drb/drb.rb', line 1062

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.



1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
# File 'lib/drb/drb.rb', line 1101

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.



1021
1022
1023
1024
1025
1026
1027
1028
# File 'lib/drb/drb.rb', line 1021

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.



1038
1039
1040
1041
1042
1043
# File 'lib/drb/drb.rb', line 1038

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.



1046
1047
1048
# File 'lib/drb/drb.rb', line 1046

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.



1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
# File 'lib/drb/drb.rb', line 1139

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.



1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
# File 'lib/drb/drb.rb', line 1126

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?



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

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

#__drbrefObject

Get the reference of the object, if local.



1081
1082
1083
# File 'lib/drb/drb.rb', line 1081

def __drbref
  @ref
end

#__drburiObject

Get the URI of the remote object.



1076
1077
1078
# File 'lib/drb/drb.rb', line 1076

def __drburi
  @uri
end

#_dump(lv) ⇒ Object

Marshall this object.

The URI and ref of the object are marshalled.



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

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



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

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

#pretty_print(q) ⇒ Object

:nodoc:



1153
1154
1155
# File 'lib/drb/drb.rb', line 1153

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

#pretty_print_cycle(q) ⇒ Object

:nodoc:



1157
1158
1159
1160
1161
1162
# File 'lib/drb/drb.rb', line 1157

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)


1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
# File 'lib/drb/drb.rb', line 1089

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