.primary
Returns the first advertised TupleSpace.
# File 'lib/rinda/ring.rb', line 299
def self.primary finger.primary end
123456789_123456789_123456789_123456789_123456789_
Relationships & Source Files | |
Inherits: | Object |
Defined in: | lib/rinda/ring.rb |
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.
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
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.
Creates a singleton RingFinger
and looks for a RingServer.
Creates a new RingFinger
that will look for RingServers at #port on the addresses in #broadcast_list.
Returns the first advertised TupleSpace.
Contains all discovered TupleSpaces except for the primary.
The list of addresses where RingFinger
will send query packets.
Maximum number of hops for sent multicast packets (if using a multicast address in the broadcast list).
The interface index to send IPv6 multicast packets from.
The port that RingFinger
will send query packets to.
Contain the first advertised TupleSpace after lookup_ring_any is called.
Iterates over all discovered TupleSpaces starting with the primary.
Looks up RingServers waiting timeout
seconds.
Returns the first found remote TupleSpace.
Contains all discovered TupleSpaces except for the primary.
Creates a socket for address
with the appropriate multicast options for multicast addresses.
RingFinger
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 '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 singleton RingFinger
and looks for a RingServer. Returns the created RingFinger
.
# File 'lib/rinda/ring.rb', line 288
def self.finger unless @@finger @@finger = self.new @@finger.lookup_ring_any end @@finger end
Returns the first advertised TupleSpace.
# File 'lib/rinda/ring.rb', line 299
def self.primary finger.primary end
Contains all discovered TupleSpaces except for the primary.
# File 'lib/rinda/ring.rb', line 306
def self.to_a finger.to_a end
The list of addresses where RingFinger
will send query packets.
# File 'lib/rinda/ring.rb', line 313
attr_accessor :broadcast_list
Maximum number of hops for sent multicast packets (if using a multicast address in the broadcast list). The default is 1 (same as UDP broadcast).
# File 'lib/rinda/ring.rb', line 320
attr_accessor :multicast_hops
The interface index to send IPv6 multicast packets from.
# File 'lib/rinda/ring.rb', line 325
attr_accessor :multicast_interface
The port that RingFinger
will send query packets to.
# File 'lib/rinda/ring.rb', line 330
attr_accessor :port
Contain the first advertised TupleSpace after lookup_ring_any is called.
# File 'lib/rinda/ring.rb', line 335
attr_accessor :primary
Iterates over all discovered TupleSpaces starting with the primary.
# File 'lib/rinda/ring.rb', line 364
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 '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| (it, msg) end sleep(timeout) end
Returns the first found remote TupleSpace. Any further recovered TupleSpaces can be found by calling .to_a.
# File '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
Creates a socket for address
with the appropriate multicast options for multicast addresses.
# File 'lib/rinda/ring.rb', line 416
def make_socket(address) # :nodoc: addrinfo = Addrinfo.udp(address, @port) soc = Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) begin if addrinfo.ipv4_multicast? then soc.setsockopt(Socket::Option.ipv4_multicast_loop(1)) soc.setsockopt(Socket::Option.ipv4_multicast_ttl(@multicast_hops)) elsif addrinfo.ipv6_multicast? then soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_LOOP, true) soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_HOPS, [@multicast_hops].pack('I')) soc.setsockopt(:IPPROTO_IPV6, :IPV6_MULTICAST_IF, [@multicast_interface].pack('I')) else soc.setsockopt(:SOL_SOCKET, :SO_BROADCAST, true) end soc.connect(addrinfo) rescue Exception soc.close raise end soc end
# File 'lib/rinda/ring.rb', line 443
def (address, ) # :nodoc: soc = make_socket(address) soc.send(, 0) rescue nil ensure soc.close if soc end
Contains all discovered TupleSpaces except for the primary.
# File 'lib/rinda/ring.rb', line 357
def to_a @rings end