bool ClusterTopologyMonitor::get_possible_writer_conn()

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;
}