snaplock: snaplock::snaplock Class Reference

#include <snaplock.h>

Inheritance diagram for snaplock::snaplock:
Collaboration diagram for snaplock::snaplock:
Classes class  computer_t   struct  message_cache   Public Types typedef std::shared_ptr< snaplockpointer_t   Public Member Functions  snaplock (int argc, char *argv[])  Initializes a snaplock object. More...
   snaplock (snaplock const &rhs)=delete   virtual ~snaplock ()  Do some clean ups. More...
  void cleanup ()  Clean timed out entries if any. More...
  void debug_info ()   snaplock_ticket::pointer_t find_first_lock (QString const &object_name)   int get_computer_count () const  Return the number of known computers running snaplock. More...
  snaplock_ticket::key_map_t const get_entering_tickets (QString const &object_name)  Get a reference to the list of entering tickets. More...
  snaplock_ticket::ticket_id_t get_last_ticket (QString const &object_name)  Determine the last ticket defined in this snaplock. More...
  computer_t::pointer_t get_leader_a () const   computer_t::pointer_t get_leader_b () const   QString const & get_server_name () const  Get the name of the server we are running on. More...
  void info ()  Output various data about the snaplock current status. More...
  computer_t::pointer_t is_leader (QString id=QString()) const  Check whether we are a leader. More...
  bool is_ready () const  Check whethre snaplock is ready to process lock requests. More...
  void lock_exiting (snap::snap_communicator_message &message)  Used to simulate a LOCKEXITING message. More...
  snaplockoperator= (snaplock const &rhs)=delete   void process_connection (int const s)   int quorum () const  Calculate the quorum number of computers. More...
  virtual void ready (snap::snap_communicator_message &message) override  Send the CLUSTERSTATUS to snapcommunicator. More...
  void run ()  Run the snaplock daemon. More...
  virtual bool send_message (snap::snap_communicator_message const &message, bool cache=false) override  Forward the message to the messenger. More...
  QString serialized_tickets ()   void set_ticket (QString const &object_name, QString const &key, snaplock_ticket::pointer_t ticket)  Set the ticket. More...
  virtual void stop (bool quitting) override  Called whenever we receive the STOP command or equivalent. More...
  void tool_message (snap::snap_communicator_message const &message)  Process a message received from Snap! Communicator. More...
  Static Public Member Functions static void sighandler (int sig)  A static function to capture various signals. More...
  static void sigloghandler (int sig)   Static Public Attributes static int64_t const DEFAULT_TIMEOUT = 5   static int64_t const MIN_TIMEOUT = 3   Private Member Functions void activate_first_lock (QString const &object_name)  Make sure the very first ticket is marked as LOCKED. More...
  void check_lock_status ()   void election_status ()   void forward_message_to_leader (snap::snap_communicator_message &message)  Forward a user message to a leader. More...
  void get_parameters (snap::snap_communicator_message const &message, QString *object_name, pid_t *client_pid, time_t *timeout, QString *key, QString *source)  Try to get a set of parameters. More...
  void msg_absolutely (snap::snap_communicator_message &message)  Lock the resource after confirmation that client is alive. More...
  void msg_activate_lock (snap::snap_communicator_message &message)  Acknowledge the ACTIVATELOCK with what we think is our first lock. More...
  void msg_add_ticket (snap::snap_communicator_message &message)  Add a ticket from another snaplock. More...
  void msg_cluster_down (snap::snap_communicator_message &message)   void msg_cluster_up (snap::snap_communicator_message &message)   void msg_drop_ticket (snap::snap_communicator_message &message)  One of the snaplock processes asked for a ticket to be dropped. More...
  void msg_get_max_ticket (snap::snap_communicator_message &message)  Search for the largest ticket. More...
  void msg_list_tickets (snap::snap_communicator_message &message)  Generate the output for "snaplock --list". More...
  void msg_lock (snap::snap_communicator_message &message)  Lock the resource. More...
  void msg_lock_activated (snap::snap_communicator_message &message)  Acknowledgement of the lock to activate. More...
  void msg_lock_entered (snap::snap_communicator_message &message)  Tell all the tickets that we received a LOCKENTERED message. More...
  void msg_lock_entering (snap::snap_communicator_message &message)  Remove a ticket we are done with (i.e. unlocked). More...
  void msg_lock_exiting (snap::snap_communicator_message &message)  Remove a ticket we are done with (i.e. unlocked). More...
  void msg_lock_failed (snap::snap_communicator_message &message)  Acknowledgement a lock failure. More...
  void msg_lock_leaders (snap::snap_communicator_message &message)   void msg_lock_started (snap::snap_communicator_message &message)  Called whenever a snaplock computer is acknowledging itself. More...
  void msg_lock_status (snap::snap_communicator_message &message)  A service asked about the lock status. More...
  void msg_lock_tickets (snap::snap_communicator_message &message)  Another snaplock is sending us its list of tickets. More...
  void msg_max_ticket (snap::snap_communicator_message &message)  Search for the largest ticket. More...
  void msg_server_gone (snap::snap_communicator_message &message)  Called whenever a remote connection is disconnected. More...
  void msg_status (snap::snap_communicator_message &message)  With the STATUS message we know of new snapcommunicators. More...
  void msg_ticket_added (snap::snap_communicator_message &message)  Acknowledgement that the ticket was properly added. More...
  void msg_ticket_ready (snap::snap_communicator_message &message)  Let other leaders know that the ticket is ready. More...
  void msg_unlock (snap::snap_communicator_message &message)  Unlock the resource. More...
  void send_lockstarted (snap::snap_communicator_message const *message)   void synchronize_leaders ()  Synchronize leaders. More...
  void ticket_list (snap::snap_communicator_message const &message)  Print out the resulting list of tickets. More...
  Private Attributes snap::snap_communicator::pointer_t f_communicator = snap::snap_communicator::pointer_t()   QString f_communicator_addr = QString("localhost")   int f_communicator_port = 4040   computer_t::map_t f_computers = computer_t::map_t()   snap::snap_config f_config   bool f_debug = false   snaplock_debug_info::pointer_t f_debug_info = snaplock_debug_info::pointer_t()   bool f_debug_lock_messages = false   int64_t f_election_date = 0   snaplock_ticket::object_map_t f_entering_tickets = snaplock_ticket::object_map_t()   QString f_host_list = QString("localhost")   snaplock_info::pointer_t f_info = snaplock_info::pointer_t()   snaplock_interrupt::pointer_t f_interrupt = snaplock_interrupt::pointer_t()   computer_t::vector_t f_leaders = computer_t::vector_t()   QString f_lock_status = QString("NOLOCK")   QString f_log_conf = QString("/etc/snapwebsites/logger/snaplock.properties")   message_cache::vector_t f_message_cache = message_cache::vector_t()   snaplock_messenger::pointer_t f_messenger = snaplock_messenger::pointer_t()   QString f_my_id = QString()   QString f_my_ip_address = QString()   size_t f_neighbors_count = 0   size_t f_neighbors_quorum = 0   int f_next_leader = 0   advgetopt::getopt f_opt   time_t f_pace_lockstarted = 0   QString f_server_name = QString()   QString f_service_name = QString("snaplock")   time_t f_start_time = -1   bool f_stop_received = false   snaplock_ticket::serial_t f_ticket_serial = 0   snaplock_ticket::object_map_t f_tickets = snaplock_ticket::object_map_t()   snaplock_timer::pointer_t f_timer = snaplock_timer::pointer_t()   Static Private Attributes static snap::dispatcher< snaplock >::dispatcher_match::vector_t const g_snaplock_service_messages  List of snaplock commands. More...
  Detailed Description

Definition at line 317 of file snaplock.h.

Member Typedef Documentation
typedef std::shared_ptr<snaplock> snaplock::snaplock::pointer_t

Definition at line 323 of file snaplock.h.

Constructor & Destructor Documentation
snaplock::snaplock::snaplock ( int  argc, char *  argv[]  )

This function parses the command line arguments, reads configuration files, setups the logger.

It also immediately executes a –help or a –version command line option and exits the process if these are present.

Parameters
[in]argcThe number of arguments in the argv array. [in]argvThe array of argument strings.

Definition at line 596 of file snaplock.cpp.

snaplock::snaplock::snaplock ( snaplock const &  rhs) delete
snaplock::snaplock::~snaplock ( ) virtual

At this point, the destructor is present mainly because we have some virtual functions.

Definition at line 762 of file snaplock.cpp.

Member Function Documentation
void snaplock::snaplock::activate_first_lock ( QString const &  object_name) private

This function is called whenever the f_tickets map changes (more specifically, one of its children) to make sure that the first ticket is clearly marked as being locked. Most of the time this happens when we add and when we remove tickets.

Note that the function may be called many times even though the first ticket does not actually change. Generally this is fine although each time it sends an ACTIVATELOCK message so we want to limit the number of calls to make sure we do not send too many possibly confusing messages.

Note
We need the ACTIVATELOCK and LOCKACTIVATED messages to make sure that we only activate the very first lock which we cannot be sure of on our own because all the previous messages are using the QUORUM as expected and thus our table of locks may not be complete at any one time.
Parameters
[in]object_nameThe name of the object which very first ticket may have changed.

Definition at line 3564 of file snaplock.cpp.

void snaplock::snaplock::check_lock_status ( ) private

Definition at line 1571 of file snaplock.cpp.

void snaplock::snaplock::cleanup ( )

This function goes through the list of tickets and entering entries and removes any one of them that timed out. This is important if a process dies and does not properly remove its locks.

Definition at line 3903 of file snaplock.cpp.

Referenced by snaplock::snaplock_timer::process_timeout().

void snaplock::snaplock::debug_info ( )

Definition at line 1272 of file snaplock.cpp.

Referenced by snaplock::snaplock_debug_info::process_signal().

void snaplock::snaplock::election_status ( ) private

Definition at line 1403 of file snaplock.cpp.

snaplock_ticket::pointer_t snaplock::snaplock::find_first_lock ( QString const &  object_name)

Definition at line 3579 of file snaplock.cpp.

void snaplock::snaplock::forward_message_to_leader ( snap::snap_communicator_message &  message) private

The user may send a LOCK or an UNLOCK command to the snaplock system. Those messages need to be forwarded to a leader to work as expected. If we are not a leader, then we need to call this function to forward the message.

Note that we do not make a copy of the message because we do not expect it to be used any further after this call so we may as well update that message. It should not be destructive at all anyway.

Parameters
[in,out]messageThe message being forwarded to a leader.

Definition at line 3875 of file snaplock.cpp.

int snaplock::snaplock::get_computer_count ( ) const

This function is used by the snaplock_ticket objects to calculate the quorum so as to know how many computers need to reply to our messages before we can be sure we got the correct results.

Returns
The number of instances of snaplock running and connected.

Definition at line 973 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::send_message_to_leaders().

snaplock_ticket::key_map_t const snaplock::snaplock::get_entering_tickets ( QString const &  object_name)

This function returns a constant reference to the list of entering tickets. This is used by the snaplock_ticket::add_ticket() function in order to know once all entering tickets are done so the algoritm can move forward.

Parameters
[in]nameThe name of the object being locked.
Returns
A constant copy of the list of entering tickets.

Definition at line 4120 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::add_ticket().

snaplock_ticket::ticket_id_t snaplock::snaplock::get_last_ticket ( QString const &  object_name)

This function loops through the existing tickets and returns the largest ticket number it finds.

Note that the number returned is the last ticket. At some point the algoritym need to add one to it before assigning the number to a new ticket.

If no ticket were defined for object_name or we are dealing with that object very first ticket, then the function returns NO_TICKET (which is 0.)

Parameters
[in]object_nameThe name of the object for which the last ticket number is being sought.
Returns
The last ticket number or NO_TICKET.

Definition at line 4064 of file snaplock.cpp.

References snaplock::snaplock_ticket::NO_TICKET.

Referenced by snaplock::snaplock_ticket::entered().

snaplock::computer_t::pointer_t snaplock::snaplock::get_leader_a ( ) const

Definition at line 1182 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::send_message_to_leaders().

snaplock::computer_t::pointer_t snaplock::snaplock::get_leader_b ( ) const

Definition at line 1208 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::send_message_to_leaders().

void snaplock::snaplock::get_parameters ( snap::snap_communicator_message const &  message, QString *  object_name, pid_t *  client_pid, time_t *  timeout, QString *  key, QString *  source  ) private

This function attempts to get the specified set of parameters from the specified message.

The function throws if a parameter is missing or invalid (i.e. an integer is not valid.)

Note
The timeout parameter is always viewed as optional. It is set to "now + DEFAULT_TIMEOUT" if undefined in the message. If specified in the message, there is no minimum or maximum (i.e. it may already have timed out.)
Exceptions
snap_communicator_invalid_messageIf a required parameter (object_name, client_pid, or key) is missing then this exception is raised. You will have to fix your software to avoid the exception.
Parameters
[in]messageThe message from which we get parameters. [out]object_nameA pointer to a QString that receives the object name. [out]client_pidA pointer to a pid_t that receives the client pid. [out]timeoutA pointer to an int64_t that receives the timeout date in seconds. [out]keyA pointer to a QString that receives the key parameter. [out]sourceA pointer to a QString that receives the source parameter.
Returns
true if all specified parameters could be retrieved.

Definition at line 2197 of file snaplock.cpp.

QString const & snaplock::snaplock::get_server_name ( ) const

This function returns the name of the server this instance of snaplock is running. It is used by the ticket implementation to know whether to send a reply to the snap_lock object (i.e. at this time we can send messages to that object only from the server it was sent from.)

Returns
The name of the server snaplock is running on.

Definition at line 1019 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::lock_activated(), and snaplock::snaplock_ticket::lock_failed().

void snaplock::snaplock::info ( )

This function outputs the current status of a snaplock daemon to the snaplock.log file.

This is used to debug a snaplock instance and make sure that the state is how you would otherwise expect it to be.

Definition at line 1243 of file snaplock.cpp.

Referenced by snaplock::snaplock_info::process_signal().

snaplock::computer_t::pointer_t snaplock::snaplock::is_leader ( QString  id = QString()) const

This function goes through the list of leaders to determine whether this snaplock is one of them, if so it returns that leader computer_t object. Otherwise it returns a null pointer.

Warning
This function is considered slow since it goes through the list each time. On the other hand, it's only 1 to 3 leaders. Yet, you should cache the result within your function if you need to call the function multiple times, as in:
// ... then use `leader` any number of times ...
This done that way so the function is dynamic and the result can change over time.
Parameters
[in]idThe identifier of the leader to search, if empty, default to f_my_id (i.e. whether this snaplock is a leader).
Returns
Our computer_t::pointer_t or a null pointer.

Definition at line 1163 of file snaplock.cpp.

bool snaplock::snaplock::is_ready ( ) const

This function checks whether snaplock is ready by looking at whether it has leaders and if so, whether each leader is connected.

Once both tests succeeds, this snaplock can forward the locks to the leaders. If it is a leader itself, it can enter a ticket in the selection and message both of the other leaders about it.

Returns
true once locks can be processed.

Definition at line 1036 of file snaplock.cpp.

void snaplock::snaplock::lock_exiting ( snap::snap_communicator_message &  message)

This function is called to simulate sending a LOCKEXITING to the snaplock object from the snaplock_ticket object.

Parameters
[in]messageThe LOCKEXITING message with proper object name and key.

Definition at line 4139 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::ticket_added().

void snaplock::snaplock::msg_absolutely ( snap::snap_communicator_message &  message) private

This message is expected just after we sent an ALIVE message to the client.

Whenever a leader dies, we suspect that the client may have died with it so we send it an ALIVE message to know whether it is worth the trouble of entering that lock.

Parameters
[in]messageThe ABSOLUTE message to handle.

Definition at line 2285 of file snaplock.cpp.

void snaplock::snaplock::msg_activate_lock ( snap::snap_communicator_message &  message) private

This function replies to an ACTIVATELOCK request with what we think is the first lock for the spcified object.

Right now, we disregard the specified key. There is nothing we can really do with it here.

If we do not have a ticket for the specified object (something that could happen if the ticket just timed out) then we still have to reply, only we let the other leader know that we have no clue what he is talking about.

Parameters
[in]messageThe message being processed.

Definition at line 3343 of file snaplock.cpp.

void snaplock::snaplock::msg_add_ticket ( snap::snap_communicator_message &  message) private

Tickets get duplicated on the snaplock leaders.

Note
Although we only need a QUORUM number of nodes to receive a copy of the data, the data still get broadcast to all the snaplock leaders. After this message arrives any one of the snaplock process can handle the unlock if the UNLOCK message gets sent to another process instead of the one which first created the ticket. This is the point of the implementation since we want to be fault tolerant (as in if one of the leaders goes down, the locking mechanism still works.)
Parameters
[in]messageThe ADDTICKET message being handled.

Definition at line 3120 of file snaplock.cpp.

void snaplock::snaplock::msg_cluster_down ( snap::snap_communicator_message &  message) private

Definition at line 1381 of file snaplock.cpp.

void snaplock::snaplock::msg_cluster_up ( snap::snap_communicator_message &  message) private

Definition at line 1366 of file snaplock.cpp.

void snaplock::snaplock::msg_drop_ticket ( snap::snap_communicator_message &  message) private

This function searches for the specified ticket and removes it from this snaplock.

If the specified ticket does not exist, nothing happens.

Warning
The DROPTICKET event receives either the ticket key (if available) or the entering key (when the ticket key was not yet available.) Note that the ticket key should always exists by the time a DROPTICKET happens, but just in case this allows the drop a ticket at any time.
Parameters
[in]messageThe message just received.

Definition at line 2972 of file snaplock.cpp.

void snaplock::snaplock::msg_get_max_ticket ( snap::snap_communicator_message &  message) private

This function searches the list of tickets for the largest one and returns that number.

Returns
The largest ticket number that currently exist in the list of tickets.

Definition at line 3052 of file snaplock.cpp.

void snaplock::snaplock::msg_list_tickets ( snap::snap_communicator_message &  message) private

This function loops over the list of tickets and outpurs a string that it sends back to the snaplock --list command for printing to the user.

Parameters
[in]messageThe message to reply to.

Definition at line 1304 of file snaplock.cpp.

void snaplock::snaplock::msg_lock ( snap::snap_communicator_message &  message) private

This function locks the specified resource object_name. It returns when the resource is locked or when the lock timeout is reached.

See the snaplock_ticket class for more details about the locking mechanisms (algorithm and MSC implementation).

Note that if lock() is called with an empty string then the function unlocks the lock and returns immediately with false. This is equivalent to calling unlock().

Note
The function reloads all the parameters (outside of the table) because we need to support a certain amount of dynamism. For example, an administrator may want to add a new host on the system. In that case, the list of host changes and it has to be detected here.
Attention
The function accepts a "serial" parameter in the message. This is only used internally when a leader is lost and a new one is assigned a lock which would otherwise fail.
Warning
The object name is left available in the lock table. Do not use any secure/secret name/word, etc. as the object name.
Bug:
At this point there is no proper protection to recover from errors that would happen while working on locking this entry. This means failures may result in a lock that never ends.
Parameters
[in]messageThe lock message.
Returns
true if the lock was successful, false otherwise.
See also
unlock()

Definition at line 2377 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_activated ( snap::snap_communicator_message &  message) private

This function is an acknowledgement that the lock can now be activated. This is true only if the 'key' and 'other_key' are a match, though.

Parameters
[in]messageThe message to be managed.

Definition at line 3392 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_entered ( snap::snap_communicator_message &  message) private

This function calls all the tickets entered() function which process the LOCKENTERED message.

We pass the key and "our ticket" number along so it can actually create the ticket if required.

Parameters
[in]messageThe LOCKENTERED message.

Definition at line 2870 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_entering ( snap::snap_communicator_message &  message) private

This command drops the specified ticket (object_name).

Parameters
[in]messageThe entering message.

Definition at line 2726 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_exiting ( snap::snap_communicator_message &  message) private

This command drops the specified ticket (object_name).

Parameters
[in]messageThe entering message.

Definition at line 2894 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_failed ( snap::snap_communicator_message &  message) private

This function handles the LOCKFAILED event that another leader may send to us. In that case we have to stop the process.

LOCKFAILED can happen mainly because of tainted data so we should never get here within a leader. However, with time we may add a few errors which could happen for other reasons than just tainted data.

When this function finds an entering ticket or a plain ticket to remove according to the object name and key found in the LOCKFAILED message, it forwards the LOCKFAILED message to the server and service found in the ticket.

Todo:
This function destroys a ticket even if it is already considered locked. Make double sure that this is okay with a LOCKFAILED sent to the client.
Warning
Although this event should not occur, it is problematic since anyone can send a LOCKFAILED message here and as a side effect destroy a perfectly valid ticket.
Parameters
[in]messageThe message to be managed.

Definition at line 3442 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_leaders ( snap::snap_communicator_message &  message) private

Definition at line 1653 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_started ( snap::snap_communicator_message &  message) private

This function gets called on a LOCKSTARTED event which is sent whenever a snaplock process is initialized on a computer.

The message is expected to include the computer name. At this time we cannot handle having more than one instance one the same computer.

Parameters
[in]messageThe LOCKSTARTED message.

Definition at line 1724 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_status ( snap::snap_communicator_message &  message) private

The lock status is whether the snaplock service is ready to receive LOCK messages (LOCKREADY) or is still waiting on a CLUSTERUP and LOCKLEADERS to happen (NOLOCK.)

Note that LOCK messages are accepted while the lock service is not yet ready, however, those are cached and it is more likely that they will timeout.

Parameters
[in]messageThe message to reply to.

Definition at line 1862 of file snaplock.cpp.

void snaplock::snaplock::msg_lock_tickets ( snap::snap_communicator_message &  message) private

Whenever a snaplock dies, a new one is quickly promoted as a leader and that new leader would have no idea about the existing tickets (locks) so the other two send it a LOCKTICKETS message.

The tickets are defined in the parameter of the same name using the serialization function to transform the objects in a string. Here we can unserialize that string accordingly.

First we extract the object name and entering key to see whether we have that ticket already defined. If so, then we unserialize in that existing object. The extraction is additive so we can do it any number of times.

Parameters
[in]messageThe message to reply to.

Definition at line 1889 of file snaplock.cpp.

void snaplock::snaplock::msg_max_ticket ( snap::snap_communicator_message &  message) private

This function searches the list of tickets for the largest one and records that number.

If a quorum is reached when adding this ticket, then an ADDTICKET reply is sent back to the sender.

Parameters
[in]messageThe MAXTICKET message being handled.

Definition at line 3085 of file snaplock.cpp.

void snaplock::snaplock::msg_server_gone ( snap::snap_communicator_message &  message) private

This function is used to know that a remote connection was disconnected.

We receive the HANGUP whenever a remote connection hangs up or snapcommunicator received a DISCONNECT message.

This allows us to manage the f_computers list of computers running snaplock.

Parameters
[in]messageThe LOCKSTARTED message.

Definition at line 2055 of file snaplock.cpp.

void snaplock::snaplock::msg_status ( snap::snap_communicator_message &  message) private

This function captures the STATUS message and if it sees that the name of the service is "remote communicator connection" then it sends a new LOCKSTARTED message to make sure that all snaplock's are aware of us.

Parameters
[in]messageThe LOCKSTARTED message.

Definition at line 2014 of file snaplock.cpp.

void snaplock::snaplock::msg_ticket_added ( snap::snap_communicator_message &  message) private

This function gets called whenever the ticket was added on another leader.

Parameters
[in]messageThe TICKETADDED message being handled.

Definition at line 3254 of file snaplock.cpp.

void snaplock::snaplock::msg_ticket_ready ( snap::snap_communicator_message &  message) private

This message is received when the owner of a ticket marks a ticket as ready. This means the ticket is available for locking.

Parameters
[in]messageThe TICKETREADY message.

Definition at line 3309 of file snaplock.cpp.

void snaplock::snaplock::msg_unlock ( snap::snap_communicator_message &  message) private

This function unlocks the resource specified in the call to lock().

Parameters
[in]messageThe unlock message.
See also
lock()

Definition at line 2653 of file snaplock.cpp.

snaplock& snaplock::snaplock::operator= ( snaplock const &  rhs) delete
void snaplock::snaplock::process_connection ( int const  s)
int snaplock::snaplock::quorum ( ) const

This function dynamically recalculates the QUORUM that is required to make sure that a value is valid between all the running computers.

Because the network can go up and down (i.e. clashes, busy, etc.) the time it takes to get an answer from a computer can be really high. This is generally not acceptable when attempting to do a lock as quickly as possible (i.e. low microseconds).

The way to avoid having to wait for all the computers to answer is to use the quorum number of computers which is a little more than half:

So if you using 4 or 5 computers for the lock, we need an answer from 3 computers to make sure that we have the correct value.

As computers running snaplock appear and disappear, the quorum number will change, dynamically.

Definition at line 1003 of file snaplock.cpp.

void snaplock::snaplock::ready ( snap::snap_communicator_message &  message) overridevirtual

This function builds a message and sends it to snapcommunicator.

The CLUSTERUP and CLUSTERDOWN messages are sent only when that specific event happen and until then we do not know what the state really is (although we assume the worst and use CLUSTERDOWN until we get a reply.)

Definition at line 1355 of file snaplock.cpp.

void snaplock::snaplock::run ( )

This function is the core function of the daemon. It runs the loop used to lock processes from any number of computers that have access to the snaplock daemon network.

Definition at line 773 of file snaplock.cpp.

void snaplock::snaplock::send_lockstarted ( snap::snap_communicator_message const *  message) private

Definition at line 1608 of file snaplock.cpp.

bool snaplock::snaplock::send_message ( snap::snap_communicator_message const &  message, bool  cache = false  ) overridevirtual

The dispatcher needs to be able to send messages (some replies are sent from the dispatcher code directly). This function allows for such to happen.

The function simply forwards the messages to the messenger queue.

Parameters
[in]messageThe message to be forwarded. [in]cacheWhether the message can be cached if it can't be dispatched immediately.

Definition at line 958 of file snaplock.cpp.

QString snaplock::snaplock::serialized_tickets ( )

Definition at line 4291 of file snaplock.cpp.

void snaplock::snaplock::set_ticket ( QString const &  object_name, QString const &  key, snaplock_ticket::pointer_t  ticket  )

Once a ticket was assigned a valid identifier (see get_last_ticket()) it can be assigned as a ticket. This function does that. Now this is an official ticket.

Parameters
[in]object_nameThe name of the object being locked. [in]keyThe ticket key (3 segments). [in]ticketThe ticket object being added.

Definition at line 4103 of file snaplock.cpp.

Referenced by snaplock::snaplock_ticket::add_ticket().

void snaplock::snaplock::sighandler ( int  sig) static

This function captures unwanted signals like SIGSEGV and SIGILL.

The handler logs the information and then the service exists. This is done mainly so we have a chance to debug problems even when it crashes on a remote server.

Warning
The signals are setup after the construction of the snaplock object because that is where we initialize the logger.
Parameters
[in]sigThe signal that was just emitted by the OS.

Definition at line 862 of file snaplock.cpp.

void snaplock::snaplock::sigloghandler ( int  sig) static

Definition at line 919 of file snaplock.cpp.

void snaplock::snaplock::stop ( bool  quitting) overridevirtual

This function makes sure the snaplock exits as quickly as possible.

  • Marks the messenger as done.
  • UNREGISTER from snapcommunicator.
Note
If the f_messenger is still in place, then just sending the UNREGISTER is enough to quit normally. The socket of the f_messenger will be closed by the snapcommunicator server and we will get a HUP signal. However, we get the HUP only because we first mark the messenger as done.
Parameters
[in]quittingSet to true if we received a QUITTING message.

Definition at line 2126 of file snaplock.cpp.

Referenced by snaplock::snaplock_interrupt::process_signal().

void snaplock::snaplock::synchronize_leaders ( ) private

This function sends various events to the other two leaders in order to get them to synchronize the tickets this snaplock currently holds.

Only leaders make use of this function.

Synchronization is necessary whenever a leader dies and another gets elected as a replacement. The replacement would have no idea of the old tickets. This function makes sure that such doesn't occur.

Note
Our test checks the validity when ONE leader is lost. If TWO of the leaders are lost at once, the algorithm may not be 100% reliable. Especially, the remaining leader may not have all the necessary information to restore all the tickets as they were expected to be.
Warning
A ticket that just arrived to a leader and was not yet forwarded to the others with the LOCKENTERING message is going to be lost no matter what.

Definition at line 3655 of file snaplock.cpp.

void snaplock::snaplock::ticket_list ( snap::snap_communicator_message const &  message) private
Parameters
[in]messageThe TICKETLIST message.

Definition at line 4271 of file snaplock.cpp.

void snaplock::snaplock::tool_message ( snap::snap_communicator_message const &  message)

This function gets called whenever the Snap! Communicator sends us a message while we act as a tool (opposed to being a daemon.)

Parameters
[in]messageThe message we just received.

Definition at line 4153 of file snaplock.cpp.

Referenced by snaplock::snaplock_tool::process_message().

Member Data Documentation
int64_t const snaplock::snaplock::DEFAULT_TIMEOUT = 5 static

Definition at line 372 of file snaplock.h.

snap::snap_communicator::pointer_t snaplock::snaplock::f_communicator = snap::snap_communicator::pointer_t() private

Definition at line 474 of file snaplock.h.

QString snaplock::snaplock::f_communicator_addr = QString("localhost") private

Definition at line 472 of file snaplock.h.

int snaplock::snaplock::f_communicator_port = 4040 private

Definition at line 473 of file snaplock.h.

computer_t::map_t snaplock::snaplock::f_computers = computer_t::map_t() private

Definition at line 489 of file snaplock.h.

snap::snap_config snaplock::snaplock::f_config private

Definition at line 467 of file snaplock.h.

bool snaplock::snaplock::f_debug = false private

Definition at line 482 of file snaplock.h.

snaplock_debug_info::pointer_t snaplock::snaplock::f_debug_info = snaplock_debug_info::pointer_t() private

Definition at line 480 of file snaplock.h.

bool snaplock::snaplock::f_debug_lock_messages = false private

Definition at line 483 of file snaplock.h.

int64_t snaplock::snaplock::f_election_date = 0 private

Definition at line 495 of file snaplock.h.

snaplock_ticket::object_map_t snaplock::snaplock::f_entering_tickets = snaplock_ticket::object_map_t() private

Definition at line 493 of file snaplock.h.

QString snaplock::snaplock::f_host_list = QString("localhost") private

Definition at line 475 of file snaplock.h.

snaplock_info::pointer_t snaplock::snaplock::f_info = snaplock_info::pointer_t() private

Definition at line 479 of file snaplock.h.

snaplock_interrupt::pointer_t snaplock::snaplock::f_interrupt = snaplock_interrupt::pointer_t() private

Definition at line 477 of file snaplock.h.

computer_t::vector_t snaplock::snaplock::f_leaders = computer_t::vector_t() private

Definition at line 490 of file snaplock.h.

QString snaplock::snaplock::f_lock_status = QString("NOLOCK") private

Definition at line 488 of file snaplock.h.

QString snaplock::snaplock::f_log_conf = QString("/etc/snapwebsites/logger/snaplock.properties") private

Definition at line 469 of file snaplock.h.

message_cache::vector_t snaplock::snaplock::f_message_cache = message_cache::vector_t() private

Definition at line 492 of file snaplock.h.

snaplock_messenger::pointer_t snaplock::snaplock::f_messenger = snaplock_messenger::pointer_t() private

Definition at line 476 of file snaplock.h.

QString snaplock::snaplock::f_my_id = QString() private

Definition at line 486 of file snaplock.h.

QString snaplock::snaplock::f_my_ip_address = QString() private

Definition at line 487 of file snaplock.h.

size_t snaplock::snaplock::f_neighbors_count = 0 private

Definition at line 484 of file snaplock.h.

size_t snaplock::snaplock::f_neighbors_quorum = 0 private

Definition at line 485 of file snaplock.h.

int snaplock::snaplock::f_next_leader = 0 private

Definition at line 491 of file snaplock.h.

advgetopt::getopt snaplock::snaplock::f_opt private

Definition at line 466 of file snaplock.h.

time_t snaplock::snaplock::f_pace_lockstarted = 0 mutableprivate

Definition at line 497 of file snaplock.h.

QString snaplock::snaplock::f_server_name = QString() private

Definition at line 470 of file snaplock.h.

QString snaplock::snaplock::f_service_name = QString("snaplock") private

Definition at line 471 of file snaplock.h.

time_t snaplock::snaplock::f_start_time = -1 private

Definition at line 468 of file snaplock.h.

bool snaplock::snaplock::f_stop_received = false private

Definition at line 481 of file snaplock.h.

snaplock_ticket::serial_t snaplock::snaplock::f_ticket_serial = 0 private

Definition at line 496 of file snaplock.h.

snaplock_ticket::object_map_t snaplock::snaplock::f_tickets = snaplock_ticket::object_map_t() private

Definition at line 494 of file snaplock.h.

snaplock_timer::pointer_t snaplock::snaplock::f_timer = snaplock_timer::pointer_t() private

Definition at line 478 of file snaplock.h.

snap::dispatcher< snaplock >::dispatcher_match::vector_t const snaplock::snaplock::g_snaplock_service_messages staticprivate

The following table defines the commands understood by snaplock that are not defined as a default by add_snap_communicator_commands().

Definition at line 464 of file snaplock.h.

int64_t const snaplock::snaplock::MIN_TIMEOUT = 3 static

Definition at line 373 of file snaplock.h.


The documentation for this class was generated from the following files:

This document is part of the Snap! Websites Project.

Copyright by Made to Order Software Corp.

Syndicate content

Snap! Websites
An Open Source CMS System in C++

Contact Us Directly