in src/failover/cluster_topology_monitor.cc [395:438]
bool ClusterTopologyMonitor::get_possible_writer_conn() {
std::lock_guard<std::mutex> node_lock(node_threads_writer_hdbc_mutex_);
std::lock_guard<std::mutex> hostinfo_lock(node_threads_writer_host_info_mutex_);
auto* local_hdbc = (node_threads_writer_hdbc_ && node_threads_writer_hdbc_.get()) ?
reinterpret_cast<SQLHDBC>(*node_threads_writer_hdbc_.get()) : SQL_NULL_HDBC;
HostInfo local_hostinfo = node_threads_writer_host_info_ ? *node_threads_writer_host_info_ : HostInfo("", 0, DOWN, false, nullptr);
if (SQL_NULL_HDBC != local_hdbc && odbc_helper_->CheckConnection(local_hdbc) && local_hostinfo.IsHostUp()) {
LOG(INFO) << "The writer host detected by the node monitors was picked up by the topology monitor: " << local_hostinfo;
std::lock_guard<std::mutex> hdbc_lock(hdbc_mutex_);
dbc_clean_up(main_hdbc_);
main_hdbc_ = std::move(node_threads_writer_hdbc_);
main_writer_host_info_ = std::make_shared<HostInfo>(local_hostinfo);
is_writer_connection_.store(true);
high_refresh_end_time_ =
std::chrono::steady_clock::time_point(std::chrono::high_resolution_clock::now().time_since_epoch()) +
high_refresh_rate_after_panic_;
// Writer verified at initial connection & failovers but want to ignore new topology requests after failover
// The first writer will be able to set from epoch to a proper end time
std::chrono::steady_clock::time_point expected = std::chrono::steady_clock::time_point{}; // Epoch
std::chrono::steady_clock::time_point new_time =
std::chrono::steady_clock::time_point(std::chrono::high_resolution_clock::now().time_since_epoch()) +
std::chrono::milliseconds(ignore_topology_request_ms_);
ignore_topology_request_end_ms_.compare_exchange_strong(expected, new_time);
node_threads_stop_.store(true);
node_monitoring_threads_.clear();
return false;
}
std::vector<HostInfo> local_topology;
{
std::lock_guard<std::mutex> topology_lock(node_threads_latest_topology_mutex_);
local_topology = node_threads_latest_topology_ ? *node_threads_latest_topology_ : std::vector<HostInfo>();
}
auto end = node_monitoring_threads_.end();
for (const HostInfo& hi : local_topology) {
std::string host_id = hi.GetHost();
if (node_monitoring_threads_.find(host_id) == end) {
node_monitoring_threads_[host_id] =
std::make_shared<NodeMonitoringThread>(this, std::make_shared<HostInfo>(hi), main_writer_host_info_);
}
}
return true;
}