HostInfo RoundRobinHostSelector::GetHost()

in src/host_selector/round_robin_host_selector.cc [45:102]


HostInfo RoundRobinHostSelector::GetHost(std::vector<HostInfo> hosts, bool is_writer,
    std::unordered_map<std::string, std::string> properties) {

    std::lock_guard<std::mutex> lock(cache_mutex);

    std::vector<HostInfo> selection;
    selection.reserve(hosts.size());

    std::copy_if(hosts.begin(), hosts.end(), std::back_inserter(selection), [&is_writer](const HostInfo& host) {
        return host.IsHostUp() && (is_writer ? host.IsHostWriter() : true);
    });

    if (selection.empty()) {
        throw std::runtime_error("No available hosts found in list");
    }

    struct {
        bool operator()(const HostInfo& a, const HostInfo& b) const {
            return a.GetHost() < b.GetHost();
        }
    } host_name_sort;
    std::sort(selection.begin(), selection.end(), host_name_sort);

    create_cache_entries(selection, properties);
    std::string cluster_id_key = selection.at(0).GetHost();
    std::shared_ptr<round_robin_property::RoundRobinClusterInfo> cluster_info = round_robin_cache.Get(cluster_id_key);

    std::shared_ptr<HostInfo> last_host = cluster_info->last_host;
    int last_host_idx = NO_HOST_IDX;
    if (last_host) {
        for (int i = 0; i < selection.size(); i++) {
            if (selection.at(i).GetHost() == last_host->GetHost()) {
                last_host_idx = i;
            }
        }
    }

    int target_host_idx;
    if (cluster_info->weigth_counter > 0 && last_host_idx != NO_HOST_IDX) {
        target_host_idx = last_host_idx;
    } else {
        if (last_host_idx != NO_HOST_IDX && last_host_idx != selection.size() - 1) {
            target_host_idx = last_host_idx + 1;
        } else {
            target_host_idx = 0;
        }
        int weight = cluster_info->default_weight;
        if (auto itr = cluster_info->cluster_weight_map.find(selection.at(target_host_idx).GetHost()); itr != cluster_info->cluster_weight_map.end()) {
            weight = itr->second;
        }
        cluster_info->weigth_counter = weight;
    }

    cluster_info->weigth_counter--;
    cluster_info->last_host = std::make_shared<HostInfo>(selection.at(target_host_idx));

    return selection.at(target_host_idx);
}