class Rinda::RingFinger

RingFinger is used by RingServer clients to discover the RingServer's TupleSpace. Typically, all a client needs to do is call ::primary to retrieve the remote TupleSpace, which it can then begin using.

Attributes

broadcast_list[RW]

The list of addresses where RingFinger will send query packets.

port[RW]

The port that RingFinger will send query packets to.

primary[RW]

Contain the first advertised TupleSpace after #lookup_ring_any is called.

Public Class Methods

finger() click to toggle source

Creates a singleton RingFinger and looks for a RingServer. Returns the created RingFinger.

# File lib/rinda/ring.rb, line 106
def self.finger
  unless @@finger
    @@finger = self.new
    @@finger.lookup_ring_any
  end
  @@finger
end
new(broadcast_list=@@broadcast_list, port=Ring_PORT) click to toggle source

Creates a new RingFinger that will look for RingServers at port on the addresses in broadcast_list.

# File lib/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
primary() click to toggle source

Returns the first advertised TupleSpace.

# File lib/rinda/ring.rb, line 117
def self.primary
  finger.primary
end
to_a() click to toggle source

Contains all discovered TupleSpaces except for the primary.

# File lib/rinda/ring.rb, line 124
def self.to_a
  finger.to_a
end

Public Instance Methods

each() { |primary| ... } click to toggle source

Iterates over all discovered TupleSpaces starting with the primary.

# File lib/rinda/ring.rb, line 164
def each
  lookup_ring_any unless @primary
  return unless @primary
  yield(@primary)
  @rings.each { |x| yield(x) }
end
lookup_ring(timeout=5, &block) click to toggle source

Looks up RingServers waiting timeout seconds. RingServers will be given block as a callback, which will be called with the remote TupleSpace.

# File lib/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
lookup_ring_any(timeout=5) click to toggle source

Returns the first found remote TupleSpace. Any further recovered TupleSpaces can be found by calling to_a.

# File lib/rinda/ring.rb, line 198
def lookup_ring_any(timeout=5)
  queue = Queue.new

  Thread.new do
    self.lookup_ring(timeout) do |ts|
      queue.push(ts)
    end
    queue.push(nil)
  end

  @primary = queue.pop
  raise('RingNotFound') if @primary.nil?

  Thread.new do
    while it = queue.pop
      @rings.push(it)
    end
  end

  @primary
end
to_a() click to toggle source

Contains all discovered TupleSpaces except for the primary.

# File lib/rinda/ring.rb, line 157
def to_a
  @rings
end