class Corosync::Quorum
Quorum
is used for tracking the health of the cluster. This simply reads the quorum state as defined by corosync. Whenever the node gains or loses quorum, a notification callback is called. You can also poll the quorum state instead of using a callback.
@example
require 'corosync/quorum' quorum = Corosync::Quorum.new quorum.on_notify do |quorate,member_list| puts "Cluster is#{quorate ? '' ' not'} quorate" puts " Members: #{member_list.join(' ')}" end quorum.connect loop do quorum.dispatch end
Attributes
The IO object containing the file descriptor notifications come across. You can use this to check for activity, but do not read anything from it. @return [IO]
Public Class Methods
Creates a new Quorum
instance
@param connect [Boolean] Whether to join the cluster immediately. If not provided, you must call {#connect} and/or {#connect} later.
@return [void]
# File lib/corosync/quorum.rb, line 32 def initialize(connect = false) @handle = nil @fd = nil @callbacks = Corosync::QuorumCallbacksT.new @callbacks[:quorum_notify_fn] = self.method(:callback_notify) self.connect if connect end
Public Instance Methods
Connect to the Quorum
service @param start [Boolean] Whether to start listening for notifications (will not make initial call to callback). @return [void]
# File lib/corosync/quorum.rb, line 45 def connect(start = false) handle_ptr = FFI::MemoryPointer.new(Corosync.find_type(:quorum_handle_t)) quorum_type_ptr = FFI::MemoryPointer.new(:uint32) Corosync.cs_send(:quorum_initialize, handle_ptr, @callbacks, quorum_type_ptr) @handle = handle_ptr.read_uint64 fd_ptr = FFI::MemoryPointer.new(:int) Corosync.cs_send(:quorum_fd_get, @handle, fd_ptr) @fd = IO.new(fd_ptr.read_int) self.start if start end
Checks for a single pending event and triggers the appropriate callback if found. @param timeout [Integer] How long to wait for an event.
* +-1+: Indefinite. Wait forever * +0+: Non-blocking. If there isn't a pending event, return immediately * +>0+: Wait the specified number of seconds.
@return [Boolean] Returns True
if an event was triggered. Otherwise False
.
# File lib/corosync/quorum.rb, line 97 def dispatch(timeout = -1) if !timeout != 0 then timeout = nil if timeout == -1 select([@fd], [], [], timeout) end begin Corosync.cs_send!(:quorum_dispatch, @handle, Corosync::CS_DISPATCH_ONE_NONBLOCKING) rescue Corosync::TryAgainError => e raise e if e.depth > 1 # this exception is from a nested corosync function, not our quorum_dispatch we just called return false end return true end
Shuts down the connection to the Quorum
service @return [void]
# File lib/corosync/quorum.rb, line 62 def finalize return if @handle.nil? Corosync.cs_send(:quorum_finalize, @handle) @handle = nil @fd = nil end
Get node quorum status @return [Boolean] Whether node is quorate.
# File lib/corosync/quorum.rb, line 136 def getquorate quorate_ptr = FFI::MemoryPointer.new(:int) Corosync.cs_send(:quorum_getquorate, @handle, quorate_ptr) quorate_ptr.read_int > 0 end
Proc to call when quorum state changes. @param block [Proc] Proc to call when quorm state changes. Pass Nil
to disable the callback. @yieldparam quorate [Boolean] Whether cluster is quorate. @yieldparam members [Array<Fixnum>] Node ID of cluster members. @return [void]
# File lib/corosync/quorum.rb, line 118 def on_notify(&block) @callback_notify = block end
Start monitoring for changes to quorum status. This basically just enables triggering the callback. If not called you can still call {#quorate?} to get quorum state. @param initial_callback [Boolean] Whether to call the callback after start. @return [Boolean]
# File lib/corosync/quorum.rb, line 75 def start(initial_callback = false) connect if @handle.nil? Corosync.cs_send(:quorum_trackstart, @handle, Corosync::CS_TRACK_CHANGES) if initial_callback and @callback_notify then @callback_notify.call(quorate?, []) end end
Stop monitoring for changes to quorum status. @return [void]
# File lib/corosync/quorum.rb, line 87 def stop Corosync.cs_send(:quorum_trackstop, @handle) end
Private Instance Methods
# File lib/corosync/quorum.rb, line 121 def callback_notify(handle, quorate, ring_id, view_list_entries, view_list_ptr) return if !@callback_notify view_list = view_list_ptr.read_array_of_type(FFI.find_type(:uint32), :read_uint32, view_list_entries) #view_list = [] #view_list_entries.times do |i| #view_list << (view_list_ptr + i * FFI.type_size(:uint32)).read_uint32 #end @callback_notify.call(quorate > 0, view_list) end