class RingyDingy::Lookup

Attributes

broadcast_list[R]

The list of addresses where ring servers will be searched-for

ring_finger[R]

The Rinda::RingFinger used to search for ring servers

Public Class Methods

new(broadcast_list = RingyDingy::BROADCAST_LIST) click to toggle source

Lists of hosts to search for ring servers. By default includes the subnet broadcast address and localhost.

# File lib/ringy_dingy/lookup.rb, line 19
def initialize broadcast_list = RingyDingy::BROADCAST_LIST
  DRb.start_service unless DRb.primary_server

  @broadcast_list = broadcast_list

  @ring_finger    = Rinda::RingFinger.new @broadcast_list
end

Public Instance Methods

each_tuple_space() { |tuple_space| ... } click to toggle source

Yields each tuple space found in the broadcast list

# File lib/ringy_dingy/lookup.rb, line 30
def each_tuple_space
  return enum_for __method__ unless block_given?

  @ring_finger.lookup_ring do |tuple_space|
    yield tuple_space
  end
end
enumerate_tuple_spaces() { |tuple_space| ... } click to toggle source

Continually checks for tuple spaces and yields found tuple spaces.

Returns a Thread that must be killed to shut down lookup:

def my_method
  thread = enumerate_tuple_spaces do |tuple_space|
    # ...
  end
ensure
  thread.kill
end
# File lib/ringy_dingy/lookup.rb, line 51
def enumerate_tuple_spaces
  Thread.start do
    loop do
      @ring_finger.lookup_ring do |tuple_space|
        yield tuple_space
      end
    end
  end
end
find(service_name) click to toggle source

Finds the first live service matching service_name on any ring server. Ring servers are discovered via the broadcast_list.

# File lib/ringy_dingy/lookup.rb, line 65
def find service_name
  found = nil

  each_tuple_space.any? do |ts|
    tuples = ts.read_all [:name, nil, DRbObject, nil]

    found = tuples.find do |_, found_service_name, service, _|
      begin
        next unless found_service_name == service_name

        if DRbObject === service then
          service.method_missing :object_id # ping service for liveness
        else
          service
        end
      rescue DRb::DRbConnError
        next
      rescue NoMethodError
        next
      end
    end
  end

  raise "unable to find service #{service_name.inspect}" unless found

  found[2]
end
wait_for(service_name) click to toggle source

Waits until service_name appears on any ring server. Returns the first service found with that name.

If you launch a service via another process use this to wait until the service comes up.

# File lib/ringy_dingy/lookup.rb, line 100
def wait_for service_name
  queue   = Queue.new
  renewer = nil

  thread = enumerate_tuple_spaces do |tuple_space|
    renewer.cancel if renewer
    renewer = RingyDingy::CancelableRenewer.new

    Thread.new do
      template = [:name, service_name, DRbObject, nil]
      begin
        tuple = tuple_space.read template, renewer

        queue.push tuple[2]
      rescue DRb::DRbConnError
      end
    end
  end

  queue.pop
ensure
  renewer.cancel
  thread.kill if thread
end