class RingyDingy
RingyDingy
registers a DRb service with a Rinda::RingServer and re-registers the service if communication with the Rinda::RingServer is ever lost.
Similarly, if the Rinda::RingServer should ever lose contact with the service the registration will be automatically dropped after a short timeout.
Example¶ ↑
my_service = MyService.new rd = RingyDingy.new my_service, :MyService rd.run DRb.thread.join
Constants
- BROADCAST_LIST
Lists of hosts to search for ring servers. By default includes the subnet broadcast address and localhost.
- VERSION
The version of
RingyDingy
you are using
Attributes
Interval to check the RingServer
for our registration information.
RingyDingy
service identifier. Use this to distinguish between RingyDingys registering the same service.
The object being provided by RingyDingy
RingyDingy
run loop thread.
Public Class Methods
Finds the first live service matching service_name
on any ring server. Ring servers are discovered via the broadcast_list
.
# File lib/ringy_dingy.rb, line 61 def self.find service_name, broadcast_list = BROADCAST_LIST RingyDingy::Lookup.new(broadcast_list).find service_name end
Creates a new RingyDingy
that registers object
as service
with optional identifier name
.
The lookup
is used to locate a Rinda::RingServer. It can be unspecified (to look for a ring server in the BROADCAST_LIST
), an Array of host names or IP address strings, a Rinda::RingFinger or RingyDingy::Lookup
using a specific broadcast list or a reference to a Rinda::TupleSpace.
# File lib/ringy_dingy.rb, line 74 def initialize object, service = :RingyDingy, name = nil, lookup = BROADCAST_LIST DRb.start_service unless DRb.primary_server @identifier = [Socket.gethostname.downcase, $PID, name].compact.join '_' @object = object @service = service || :RingyDingy @check_every = 15 @renewer = Rinda::SimpleRenewer.new @ring_finger = nil @ring_server = nil case lookup when Array then @ring_finger = Rinda::RingFinger.new lookup when Rinda::RingFinger then @ring_finger = lookup when RingyDingy::Lookup then @ring_finger = lookup.ring_finger else @ring_server = lookup end @thread = nil end
Public Instance Methods
Registers this service with the primary Rinda::RingServer.
# File lib/ringy_dingy.rb, line 105 def register reference = DRb::DRbObject.new(@object) tuple = [:name, @service, reference, @identifier] ring_server.write tuple, @renewer nil end
Looks for a registration tuple in the primary Rinda::RingServer. If a RingServer
can't be found or contacted, returns false.
# File lib/ringy_dingy.rb, line 119 def registered? registrations = ring_server.read_all [:name, @service, nil, @identifier] registrations.any? { |registration| registration[2] == @object } rescue DRb::DRbConnError @ring_server = nil return false end
Looks up the primary Rinde::RingServer.
# File lib/ringy_dingy.rb, line 131 def ring_server return @ring_server unless @ring_server.nil? @ring_server = @ring_finger.lookup_ring_any end
Starts a thread that checks for a registration tuple every check_every
seconds.
If wait
is :none
(the default) run returns immediately. If wait
is :first_register
then run blocks until the service was successfully registered.
# File lib/ringy_dingy.rb, line 158 def run wait = :none mutex = Mutex.new service_registered = ConditionVariable.new @thread = Thread.start do loop do begin register unless registered? mutex.synchronize do service_registered.signal end if wait == :first_register rescue DRb::DRbConnError @ring_server = nil rescue RuntimeError => e raise unless e.message == 'RingNotFound' end sleep @check_every end end mutex.synchronize do service_registered.wait mutex end if wait == :first_register self end
Stops checking for registration tuples.
# File lib/ringy_dingy.rb, line 189 def stop @thread.kill return nil end