247 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018 MariaDB Corporation Ab
 | |
|  *
 | |
|  * Use of this software is governed by the Business Source License included
 | |
|  * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
 | |
|  *
 | |
|  * Change Date: 2023-01-01
 | |
|  *
 | |
|  * On the date above, in accordance with the Business Source License, use
 | |
|  * of this software will be governed by version 2 or later of the General
 | |
|  * Public License.
 | |
|  */
 | |
| #pragma once
 | |
| 
 | |
| #include "clustrixmon.hh"
 | |
| #include <iostream>
 | |
| #include <sstream>
 | |
| #include <string>
 | |
| #include "clustrix.hh"
 | |
| #include "clustrixmembership.hh"
 | |
| 
 | |
| class ClustrixNode
 | |
| {
 | |
| public:
 | |
|     class Persister
 | |
|     {
 | |
|     public:
 | |
|         virtual void persist(const ClustrixNode& node) = 0;
 | |
|         virtual void unpersist(const ClustrixNode& node) = 0;
 | |
|     };
 | |
| 
 | |
|     enum
 | |
|     {
 | |
|         DEFAULT_MYSQL_PORT  = 3306,
 | |
|         DEFAULT_HEALTH_PORT = 3581,
 | |
|     };
 | |
| 
 | |
|     enum approach_t
 | |
|     {
 | |
|         APPROACH_OVERRIDE,
 | |
|         APPROACH_DEFAULT
 | |
|     };
 | |
| 
 | |
|     ClustrixNode(Persister* pPersister,
 | |
|                  const ClustrixMembership& membership,
 | |
|                  const std::string& ip,
 | |
|                  int mysql_port,
 | |
|                  int health_port,
 | |
|                  int health_check_threshold,
 | |
|                  SERVER* pServer)
 | |
|         : m_persister(*pPersister)
 | |
|         , m_id(membership.id())
 | |
|         , m_status(membership.status())
 | |
|         , m_substate(membership.substate())
 | |
|         , m_instance(membership.instance())
 | |
|         , m_ip(ip)
 | |
|         , m_mysql_port(mysql_port)
 | |
|         , m_health_port(health_port)
 | |
|         , m_health_check_threshold(health_check_threshold)
 | |
|         , m_nRunning(m_health_check_threshold)
 | |
|         , m_pServer(pServer)
 | |
|         , m_pCon(nullptr)
 | |
|     {
 | |
|         m_pServer->set_status(SERVER_MASTER | SERVER_RUNNING);
 | |
|         m_persister.persist(*this);
 | |
|     }
 | |
| 
 | |
|     ~ClustrixNode()
 | |
|     {
 | |
|         if (m_pCon)
 | |
|         {
 | |
|             mysql_close(m_pCon);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     int id() const
 | |
|     {
 | |
|         return m_id;
 | |
|     }
 | |
| 
 | |
|     Clustrix::Status status() const
 | |
|     {
 | |
|         return m_status;
 | |
|     }
 | |
| 
 | |
|     Clustrix::SubState substate() const
 | |
|     {
 | |
|         return m_substate;
 | |
|     }
 | |
| 
 | |
|     int instance() const
 | |
|     {
 | |
|         return m_instance;
 | |
|     }
 | |
| 
 | |
|     const std::string& ip() const
 | |
|     {
 | |
|         return m_ip;
 | |
|     }
 | |
| 
 | |
|     int mysql_port() const
 | |
|     {
 | |
|         return m_mysql_port;
 | |
|     }
 | |
| 
 | |
|     int health_port() const
 | |
|     {
 | |
|         return m_health_port;
 | |
|     }
 | |
| 
 | |
|     bool is_running() const
 | |
|     {
 | |
|         return m_nRunning > 0;
 | |
|     }
 | |
| 
 | |
|     void set_running(bool running, approach_t approach = APPROACH_DEFAULT)
 | |
|     {
 | |
|         if (running)
 | |
|         {
 | |
|             if (m_nRunning == 0)
 | |
|             {
 | |
|                 m_pServer->set_status(SERVER_MASTER | SERVER_RUNNING);
 | |
|                 m_persister.persist(*this);
 | |
|             }
 | |
| 
 | |
|             m_nRunning = m_health_check_threshold;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             if (m_nRunning > 0)
 | |
|             {
 | |
|                 if (approach == APPROACH_OVERRIDE)
 | |
|                 {
 | |
|                     m_nRunning = 0;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     --m_nRunning;
 | |
|                 }
 | |
| 
 | |
|                 if (m_nRunning == 0)
 | |
|                 {
 | |
|                     m_pServer->clear_status(SERVER_MASTER | SERVER_RUNNING);
 | |
|                     m_persister.unpersist(*this);
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void update(const std::string& ip,
 | |
|                 int mysql_port,
 | |
|                 int health_port)
 | |
|     {
 | |
|         bool changed = false;
 | |
| 
 | |
|         if (ip != m_ip)
 | |
|         {
 | |
|             m_ip = ip;
 | |
|             changed = true;
 | |
|         }
 | |
| 
 | |
|         if (mysql_port != m_mysql_port)
 | |
|         {
 | |
|             m_mysql_port = mysql_port;
 | |
|             m_pServer->update_port(m_mysql_port);
 | |
|             changed = true;
 | |
|         }
 | |
| 
 | |
|         if (health_port != m_health_port)
 | |
|         {
 | |
|             m_health_port = health_port;
 | |
|             changed = true;
 | |
|         }
 | |
| 
 | |
|         if (changed)
 | |
|         {
 | |
|             m_persister.persist(*this);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     void update(Clustrix::Status status, Clustrix::SubState substate, int instance)
 | |
|     {
 | |
|         m_status = status;
 | |
|         m_substate = substate;
 | |
|         m_instance = instance;
 | |
|     }
 | |
| 
 | |
|     void deactivate_server()
 | |
|     {
 | |
|         m_pServer->is_active = false;
 | |
|         m_persister.unpersist(*this);
 | |
|     }
 | |
| 
 | |
|     bool can_be_used_as_hub(const char* zName,
 | |
|                             const mxs::MonitorServer::ConnectionSettings& settings,
 | |
|                             Clustrix::Softfailed softfailed);
 | |
| 
 | |
|     SERVER* server() const
 | |
|     {
 | |
|         return m_pServer;
 | |
|     }
 | |
| 
 | |
|     MYSQL* connection() const
 | |
|     {
 | |
|         return m_pCon;
 | |
|     }
 | |
| 
 | |
|     MYSQL* release_connection()
 | |
|     {
 | |
|         MYSQL* pCon = m_pCon;
 | |
|         m_pCon = nullptr;
 | |
|         return pCon;
 | |
|     }
 | |
| 
 | |
|     std::string to_string() const
 | |
|     {
 | |
|         std::stringstream ss;
 | |
|         ss << "{" << m_id << ", " << m_ip << ", " << m_mysql_port << ", " << m_health_port << "}";
 | |
|         return ss.str();
 | |
|     }
 | |
| 
 | |
|     void print(std::ostream& o) const
 | |
|     {
 | |
|         o << to_string();
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     Persister&         m_persister;
 | |
|     int                m_id;
 | |
|     Clustrix::Status   m_status;
 | |
|     Clustrix::SubState m_substate;
 | |
|     int                m_instance;
 | |
|     std::string        m_ip;
 | |
|     int                m_mysql_port {DEFAULT_MYSQL_PORT};
 | |
|     int                m_health_port {DEFAULT_HEALTH_PORT};
 | |
|     int                m_health_check_threshold {DEFAULT_HEALTH_CHECK_THRESHOLD};
 | |
|     int                m_nRunning {0};
 | |
|     SERVER*            m_pServer {nullptr};
 | |
|     MYSQL*             m_pCon {nullptr};
 | |
| };
 | |
| 
 | |
| inline std::ostream& operator<<(std::ostream& out, const ClustrixNode& x)
 | |
| {
 | |
|     x.print(out);
 | |
|     return out;
 | |
| }
 | 
