Contain the first advertised TupleSpace after lookup_ring_any is called.
Object
RingFinger is used by RingServer clients to discover the RingServer's TupleSpace. Typically, all a client needs to do is call RingFinger.primary to retrieve the remote TupleSpace, which it can then begin using.
Creates a singleton RingFinger and looks for a RingServer. Returns the created RingFinger.
# File rinda/ring.rb, line 106
def self.finger
unless @@finger
@@finger = self.new
@@finger.lookup_ring_any
end
@@finger
end
Creates a new RingFinger that will look for RingServers at port on the addresses in broadcast_list.
# File rinda/ring.rb, line 147
def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)
@broadcast_list = broadcast_list || ['localhost']
@port = port
@primary = nil
@rings = []
end
Returns the first advertised TupleSpace.
# File rinda/ring.rb, line 117
def self.primary
finger.primary
end
Iterates over all discovered TupleSpaces starting with the primary.
# File rinda/ring.rb, line 164
def each
lookup_ring_any unless @primary
return unless @primary
yield(@primary)
@rings.each { |x| yield(x) }
end
Looks up RingServers waiting timeout seconds. RingServers will be given block as a callback, which will be called with the remote TupleSpace.
# File rinda/ring.rb, line 176
def lookup_ring(timeout=5, &block)
return lookup_ring_any(timeout) unless block_given?
msg = Marshal.dump([[:lookup_ring, DRbObject.new(block)], timeout])
@broadcast_list.each do |it|
soc = UDPSocket.open
begin
soc.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
soc.send(msg, 0, it, @port)
rescue
nil
ensure
soc.close
end
end
sleep(timeout)
end
Returns the first found remote TupleSpace. Any further recovered TupleSpaces can be found by calling to_a.
# File rinda/ring.rb, line 198
def lookup_ring_any(timeout=5)
queue = Queue.new
th = Thread.new do
self.lookup_ring(timeout) do |ts|
queue.push(ts)
end
queue.push(nil)
while it = queue.pop
@rings.push(it)
end
end
@primary = queue.pop
raise('RingNotFound') if @primary.nil?
@primary
end