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.
To find the first available remote TupleSpace:
Rinda::RingFinger.primary
To create a RingFinger
that broadcasts to a custom list:
rf = Rinda::RingFinger.new ['localhost', '192.0.2.1'] rf.primary
Rinda::RingFinger
also understands multicast addresses and sets them up properly. This allows you to run multiple RingServers on the same host:
rf = Rinda::RingFinger.new ['239.0.0.1'] rf.primary
You can set the hop count (or TTL) for multicast searches using multicast_hops
.
If you use IPv6 multicast you may need to set both an address and the outbound interface index:
rf = Rinda::RingFinger.new ['ff02::1'] rf.multicast_interface = 1 rf.primary
At this time there is no easy way to get an interface index by name.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 288
def self.finger
unless @@finger
@@finger = self.new
@@finger.lookup_ring_any
end
@@finger
end
Creates a singleton RingFinger
and looks for a RingServer
. Returns the created RingFinger
.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 344
def initialize(broadcast_list=@@broadcast_list, port=Ring_PORT)
@broadcast_list = broadcast_list || ['localhost']
@port = port
@primary = nil
@rings = []
@multicast_hops = 1
@multicast_interface = 0
end
Creates a new RingFinger
that will look for RingServers at port
on the addresses in broadcast_list
.
If broadcast_list
contains a multicast address then multicast queries will be made using the given multicast_hops
and multicast_interface.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 299
def self.primary
finger.primary
end
Returns the first advertised TupleSpace
.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 306
def self.to_a
finger.to_a
end
Contains all discovered TupleSpaces except for the primary.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 364
def each
lookup_ring_any unless @primary
return unless @primary
yield(@primary)
@rings.each { |x| yield(x) }
end
Iterates over all discovered TupleSpaces starting with the primary.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 376
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|
send_message(it, msg)
end
sleep(timeout)
end
Looks up RingServers waiting timeout
seconds. RingServers will be given block
as a callback, which will be called with the remote TupleSpace
.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 390
def lookup_ring_any(timeout=5)
queue = Thread::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
Returns the first found remote TupleSpace
. Any further recovered TupleSpaces can be found by calling to_a
.
# File tmp/rubies/ruby-3.2.0/lib/rinda/ring.rb, line 357
def to_a
@rings
end
Contains all discovered TupleSpaces except for the primary.