driver/topology_service.h (76 lines of code) (raw):
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0
// (GPLv2), as published by the Free Software Foundation, with the
// following additional permissions:
//
// This program is distributed with certain software that is licensed
// under separate terms, as designated in a particular file or component
// or in the license documentation. Without limiting your rights under
// the GPLv2, the authors of this program hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have included with the program.
//
// Without limiting the foregoing grant of rights under the GPLv2 and
// additional permission as to separately licensed software, this
// program is also subject to the Universal FOSS Exception, version 1.0,
// a copy of which can be found along with its FAQ at
// http://oss.oracle.com/licenses/universal-foss-exception.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License, version 2.0, for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// http://www.gnu.org/licenses/gpl-2.0.html.
#ifndef __TOPOLOGYSERVICE_H__
#define __TOPOLOGYSERVICE_H__
#include "MYODBC_MYSQL.h"
#include "cluster_aware_metrics_container.h"
#include "cluster_topology_info.h"
#include "connection_proxy.h"
#include <chrono>
#include <ctime>
#include <map>
#include <mutex>
#include "allowed_and_blocked_hosts.h"
// TODO - consider - do we really need miliseconds for refresh? - the default numbers here are already 30 seconds.000;
#define DEFAULT_REFRESH_RATE_IN_MILLISECONDS 30000
#define WRITER_SESSION_ID "MASTER_SESSION_ID"
#define RETRIEVE_TOPOLOGY_SQL \
"SELECT SERVER_ID, SESSION_ID, LAST_UPDATE_TIMESTAMP, REPLICA_LAG_IN_MILLISECONDS \
FROM information_schema.replica_host_status \
WHERE time_to_sec(timediff(now(), LAST_UPDATE_TIMESTAMP)) <= 300 \
ORDER BY LAST_UPDATE_TIMESTAMP DESC"
static std::map<std::string, std::shared_ptr<CLUSTER_TOPOLOGY_INFO>> topology_cache;
static std::mutex topology_cache_mutex;
class TOPOLOGY_SERVICE {
public:
TOPOLOGY_SERVICE(unsigned long dbc_id, bool enable_logging = false);
TOPOLOGY_SERVICE(const TOPOLOGY_SERVICE&);
virtual ~TOPOLOGY_SERVICE();
virtual void set_cluster_id(std::string cluster_id);
virtual void set_cluster_instance_template(
std::shared_ptr<HOST_INFO> host_template); // is this equivalent to set_cluster_instance_host
virtual std::shared_ptr<CLUSTER_TOPOLOGY_INFO> get_topology(CONNECTION_PROXY* connection, bool force_update = false);
virtual std::shared_ptr<CLUSTER_TOPOLOGY_INFO> get_filtered_topology(std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology);
virtual std::string log_topology(const std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology);
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> get_cached_topology();
std::shared_ptr<HOST_INFO> get_last_used_reader();
void set_last_used_reader(std::shared_ptr<HOST_INFO> reader);
std::set<std::string> get_down_hosts();
virtual void mark_host_down(std::shared_ptr<HOST_INFO> host);
virtual void mark_host_up(std::shared_ptr<HOST_INFO> host);
void set_refresh_rate(int refresh_rate);
void set_gather_metric(bool can_gather);
void clear_all();
void clear();
void set_allowed_and_blocked_hosts(std::shared_ptr<ALLOWED_AND_BLOCKED_HOSTS> hosts) {
this->allowed_and_blocked_hosts = hosts;
};
// Property Keys
const std::string SESSION_ID = "TOPOLOGY_SERVICE_SESSION_ID";
const std::string LAST_UPDATED = "TOPOLOGY_SERVICE_LAST_UPDATE_TIMESTAMP";
const std::string REPLICA_LAG = "TOPOLOGY_SERVICE_REPLICA_LAG_IN_MILLISECONDS";
const std::string INSTANCE_NAME = "TOPOLOGY_SERVICE_SERVER_ID";
private:
const int DEFAULT_CACHE_EXPIRE_MS = 5 * 60 * 1000; // 5 min
const std::string GET_INSTANCE_NAME_SQL = "SELECT @@aurora_server_id";
const std::string GET_INSTANCE_NAME_COL = "@@aurora_server_id";
const std::string FIELD_SERVER_ID = "SERVER_ID";
const std::string FIELD_SESSION_ID = "SESSION_ID";
const std::string FIELD_LAST_UPDATED = "LAST_UPDATE_TIMESTAMP";
const std::string FIELD_REPLICA_LAG = "REPLICA_LAG_IN_MILLISECONDS";
std::shared_ptr<FILE> logger = nullptr;
unsigned long dbc_id = 0;
protected:
const int NO_CONNECTION_INDEX = -1;
int refresh_rate_in_ms;
std::string cluster_id;
std::shared_ptr<HOST_INFO> cluster_instance_host;
std::shared_ptr<CLUSTER_AWARE_METRICS_CONTAINER> metrics_container;
std::shared_ptr<ALLOWED_AND_BLOCKED_HOSTS> allowed_and_blocked_hosts;
bool refresh_needed(std::time_t last_updated);
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> query_for_topology(CONNECTION_PROXY* connection);
std::shared_ptr<HOST_INFO> create_host(MYSQL_ROW& row);
std::string get_host_endpoint(const char* node_name);
static bool does_instance_exist(std::map<std::string, std::shared_ptr<HOST_INFO>>& instances,
std::shared_ptr<HOST_INFO> host_info);
std::shared_ptr<CLUSTER_TOPOLOGY_INFO> get_from_cache();
void put_to_cache(std::shared_ptr<CLUSTER_TOPOLOGY_INFO> topology_info);
MYSQL_RES* try_execute_query(CONNECTION_PROXY* connection_proxy, const char* query);
};
#endif /* __TOPOLOGYSERVICE_H__ */