in src/failover/failover_service.cc [497:520]
FailoverResult FailoverConnection(const char* service_id_c_str, const char* sql_state, SQLHENV henv) {
std::string cluster_id(service_id_c_str);
if (!FailoverServiceTrackerHandler::Contains(cluster_id)) {
LOG(INFO) << "[Failover Service] no tracker found for: " << cluster_id << ". Cannot perform failover.";
return FailoverResult{ .status = FAILOVER_FAILED, .hdbc = SQL_NULL_HDBC };
}
std::shared_ptr<FailoverServiceTracker> tracker = FailoverServiceTrackerHandler::Get(cluster_id);
if (nullptr == tracker->service) {
LOG(INFO) << "[Failover Service] no active Failover Service: " << cluster_id << ". Cannot perform failover.";
return FailoverResult{ .status = FAILOVER_FAILED, .hdbc = SQL_NULL_HDBC };
}
// Set flag to ensure tracker is not cleaned up during failover disconnection
tracker->failover_inprogress.fetch_add(1);
SQLHDBC local_hdbc = SQL_NULL_HDBC;
// open a new connection
SQLAllocHandle(SQL_HANDLE_DBC, henv, &local_hdbc);
FailoverStatus status = tracker->service->Failover(local_hdbc, sql_state);
tracker->failover_inprogress.fetch_sub(1);
if (FAILOVER_SUCCEED != status) {
OdbcHelper::Cleanup(SQL_NULL_HENV, local_hdbc, SQL_NULL_HSTMT);
LOG(WARNING) << "[Failover Service] Unsuccessful failover for: " << cluster_id;
}
return FailoverResult{ .status = status, .hdbc = local_hdbc };
}