| 43 | } |
| 44 | |
| 45 | IConnectionPool::Entry ConnectionPoolWithFailover::get(const ConnectionTimeouts & timeouts, |
| 46 | const Settings * settings, |
| 47 | bool /*force_connected*/) |
| 48 | { |
| 49 | TryGetEntryFunc try_get_entry = [&](NestedPool & pool, std::string & fail_message) |
| 50 | { |
| 51 | return tryGetEntry(pool, timeouts, fail_message, settings); |
| 52 | }; |
| 53 | |
| 54 | size_t offset = 0; |
| 55 | if (settings) |
| 56 | offset = settings->load_balancing_first_offset % nested_pools.size(); |
| 57 | GetPriorityFunc get_priority; |
| 58 | switch (settings ? LoadBalancing(settings->load_balancing) : default_load_balancing) |
| 59 | { |
| 60 | case LoadBalancing::NEAREST_HOSTNAME: |
| 61 | get_priority = [&](size_t i) { return hostname_differences[i]; }; |
| 62 | break; |
| 63 | case LoadBalancing::IN_ORDER: |
| 64 | get_priority = [](size_t i) { return i; }; |
| 65 | break; |
| 66 | case LoadBalancing::RANDOM: |
| 67 | break; |
| 68 | case LoadBalancing::FIRST_OR_RANDOM: |
| 69 | get_priority = [offset](size_t i) -> size_t { return i != offset; }; |
| 70 | break; |
| 71 | case LoadBalancing::ROUND_ROBIN: |
| 72 | if (last_used >= nested_pools.size()) |
| 73 | last_used = 0; |
| 74 | ++last_used; |
| 75 | /* Consider nested_pools.size() equals to 5 |
| 76 | * last_used = 1 -> get_priority: 0 1 2 3 4 |
| 77 | * last_used = 2 -> get_priority: 5 0 1 2 3 |
| 78 | * last_used = 3 -> get_priority: 5 4 0 1 2 |
| 79 | * ... |
| 80 | * */ |
| 81 | get_priority = [&](size_t i) { ++i; return i < last_used ? nested_pools.size() - i : i - last_used; }; |
| 82 | break; |
| 83 | case LoadBalancing::REVERSE_ORDER: |
| 84 | get_priority = [&](size_t i) { return !nested_pools.empty() ? (nested_pools.size() - 1 - i % nested_pools.size()) : i; }; |
| 85 | break; |
| 86 | } |
| 87 | |
| 88 | UInt64 max_ignored_errors = settings ? settings->distributed_replica_max_ignored_errors.value : 0; |
| 89 | bool fallback_to_stale_replicas = settings ? settings->fallback_to_stale_replicas_for_distributed_queries.value : true; |
| 90 | |
| 91 | return Base::get(max_ignored_errors, fallback_to_stale_replicas, try_get_entry, get_priority); |
| 92 | } |
| 93 | |
| 94 | Int64 ConnectionPoolWithFailover::getPriority() const |
| 95 | { |
no test coverage detected