Class: Corosync::Votequorum

Inherits:
Object
  • Object
show all
Defined in:
lib/corosync/votequorum.rb

Overview

Votequorum is used for tracking the health of the cluster. This monitors the quorum state as configured. Whenever the node gains or loses quorum, a notification callback is called. You can also poll the quorum state instead of using a callback.


Examples:

require 'corosync/votequorum'
vq = Corosync::Votequorum.new
vq.on_notify do |quorate,node_list|
  puts "Cluster is#{quorate ? '' ' not'} quorate"
  puts "  Nodes:"
  node_list.each do |name,state|
    puts "    #{name}=#{state}"
  end
end
vq.connect
loop do
  vq.dispatch
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(connect = false) ⇒ void

Creates a new Votequorum instance

Parameters:

  • connect (Boolean) (defaults to: false)

    Whether to join the cluster immediately. If not provided, you must call #connect and/or #connect later.



36
37
38
39
40
41
42
43
44
45
# File 'lib/corosync/votequorum.rb', line 36

def initialize(connect = false)
  @handle = nil
  @fd = nil

  @callbacks = Corosync::VotequorumCallbacksT.new
  @callbacks[:votequorum_notify_fn] = self.method(:callback_notify)
  @callbacks[:votequorum_expectedvotes_notify_fn] = self.method(:callback_expectedvotes_notify)

  self.connect if connect
end

Instance Attribute Details

#fdIO (readonly)

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.

Returns:

  • (IO)


29
30
31
# File 'lib/corosync/votequorum.rb', line 29

def fd
  @fd
end

Instance Method Details

#connect(start = false) ⇒ void

This method returns an undefined value.

Connect to the Votequorum service

Parameters:

  • start (Boolean) (defaults to: false)

    Whether to start listening for notifications (will not make initial call to callback).



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/corosync/votequorum.rb', line 50

def connect(start = false)
  handle_ptr = FFI::MemoryPointer.new(Corosync.find_type(:votequorum_handle_t))

  Corosync.cs_send(:votequorum_initialize, handle_ptr, @callbacks)

  @handle = handle_ptr.read_uint64

  fd_ptr = FFI::MemoryPointer.new(:int)
  Corosync.cs_send(:votequorum_fd_get, @handle, fd_ptr)
  @fd = IO.new(fd_ptr.read_int)

  self.start if start
end

#dispatch(timeout = -1)) ⇒ Boolean

Checks for a single pending event and triggers the appropriate callback if found.

Parameters:

  • timeout (Integer) (defaults to: -1))

    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.

Returns:

  • (Boolean)

    Returns True if an event was triggered. Otherwise False.



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/corosync/votequorum.rb', line 101

def dispatch(timeout = -1)
  if !timeout != 0 then
    timeout = nil if timeout == -1
    select([@fd], [], [], timeout)
  end

  begin
    Corosync.cs_send(:votequorum_dispatch, @handle, Corosync::CS_DISPATCH_ONE_NONBLOCKING)
  rescue Corosync::TryAgainError
    return false
  end

  return true
end

#finalizevoid

This method returns an undefined value.

Shuts down the connection to the Quorum service



66
67
68
69
70
71
72
73
# File 'lib/corosync/votequorum.rb', line 66

def finalize
  return if @handle.nil?

  Corosync.cs_send(:votequorum_finalize, @handle)

  @handle = nil
  @fd = nil
end

#info(node_id = 0) ⇒ OpenStruct

Get the votequorum info about a node. The return openstruct will contain the following keys

* node_id - Integer
* node_state - Symbol: :member or :dead or :leaving
* node_votes - Integer
* node_expected_votes - Integer
* highest_expected - Integer
* total_votes - Integer
* quorum - Integer
* flags - Array<Symbol> where each symbol is one of: :twonode, :quorate, :wait_for_all, :last_man_standing, :auto_tie_breaker, :allow_downscale, :qdevice_registered, :qdevice_alive, :qdevice_cast_vote, or :qdevice_master_wins
* qdevice_votes - Integer
* qdevice_name - String

Parameters:

  • node_id (Integer) (defaults to: 0)

    The node id to look up. 0 for the current node.

Returns:

  • (OpenStruct)


171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/corosync/votequorum.rb', line 171

def info(node_id = 0)
  info = Corosync::VotequorumInfo.new

  Corosync.cs_send(:votequorum_getinfo, @handle, node_id, info)

  info = OpenStruct.new(Hash[info.members.zip(info.values)])

  info.qdevice_name = info.qdevice_name.to_s

  flags = info.flags
  info.flags = []
  [:twonode,:quorate,:wait_for_all,:last_man_standing,:auto_tie_breaker,:allow_downscale,:qdevice_registered,:qdevice_alive,:qdevice_cast_vote,:qdevice_master_wins].each do |flag_name|
    flag_value = Corosync.const_get("VOTEQUORUM_INFO_#{flag_name.to_s.upcase}")
    info.flags << flag_name if flags & flag_value >= 1
  end

  info
  #Corosync::Votequorum::Info.new info
end

#on_expectedvotes_notify(&block) {|expected_votes| ... } ⇒ void

This method returns an undefined value.

Proc to call when the number of expected votes changes.

Parameters:

  • block (Proc)

    Proc to call when the expected votes changes. Pass Nil to disable the callback.

Yield Parameters:

  • expected_votes (Integer)

    New number of expected votes.



147
148
149
# File 'lib/corosync/votequorum.rb', line 147

def on_expectedvotes_notify(&block)
  @callback_expectedvotes_notify = block
end

#on_notify(&block) {|quorate, nodes| ... } ⇒ void

This method returns an undefined value.

Proc to call when quorum state changes.

Parameters:

  • block (Proc)

    Proc to call when quorm state changes. Pass Nil to disable the callback.

Yield Parameters:

  • quorate (Boolean)

    Whether cluster is quorate.

  • nodes (Hash)

    Hash of node IDs and their state. The state is one of :member, :dead, or :leaving



122
123
124
# File 'lib/corosync/votequorum.rb', line 122

def on_notify(&block)
  @callback_notify = block
end

#quorate?Boolean

Get whether this node is quorate or not Shorthand for #info.flags.include?(:quorate)

Returns:

  • (Boolean)


215
216
217
# File 'lib/corosync/votequorum.rb', line 215

def quorate?
  self.info.flags.include?(:quorate)
end

#set_expected(count) ⇒ void Also known as: expected=

This method returns an undefined value.

Set the number of expected votes for this node

Parameters:

  • count (Integer)


194
195
196
# File 'lib/corosync/votequorum.rb', line 194

def set_expected(count)
  Corosync.cs_send(:votequorum_setexpected, @handle, count)
end

#set_votes(count, node_id = 0) ⇒ void

This method returns an undefined value.

Set the number of votes contributed by the specified node.

Parameters:

  • count (Integer)
  • node_id (Integer) (defaults to: 0)

    The node to modify



203
204
205
# File 'lib/corosync/votequorum.rb', line 203

def set_votes(count, node_id = 0)
  Corosync.cs_send(:votequorum_setvotes, @handle, node_id, count)
end

#start(initial_callback = false) ⇒ Boolean

Start monitoring for changes to quorum status/config. This basically just enables triggering the callback. If not called you can still call #quorate? to get quorum state.

Parameters:

  • initial_callback (Boolean) (defaults to: false)

    Whether to call the callback after start.

Returns:

  • (Boolean)


79
80
81
82
83
84
85
86
87
# File 'lib/corosync/votequorum.rb', line 79

def start(initial_callback = false)
  connect if @handle.nil?

  Corosync.cs_send(:votequorum_trackstart, @handle, 0, Corosync::CS_TRACK_CHANGES)

  if initial_callback and @callback_notify then
    @callback_notify.call(quorate?)
  end
end

#stopvoid

This method returns an undefined value.

Stop monitoring for changes.



91
92
93
# File 'lib/corosync/votequorum.rb', line 91

def stop
  Corosync.cs_send(:votequorum_trackstop, @handle)
end

#votes=(count) ⇒ Object

Set the number of votes contributed by this node. Shorthand for #set_votes(count)



208
209
210
# File 'lib/corosync/votequorum.rb', line 208

def votes=(count)
  set_votes(count)
end