private boolean shutdown(long timeout, TimeUnit unit) throws InterruptedException { if (!isShutdown.compareAndSet(false, true)) return true; long start = System.nanoTime(); boolean success = true; for (HostConnectionPool pool : pools.values()) success &= pool.shutdown(timeout - Cluster.timeSince(start, unit), unit); return success; }
private boolean discardAvailableConnections(long timeout, TimeUnit unit) throws InterruptedException { long start = System.nanoTime(); boolean success = true; for (Connection connection : connections) { success &= connection.close(timeout - Cluster.timeSince(start, unit), unit); open.decrementAndGet(); } return success; }
/* * When the set of live nodes change, the loadbalancer will change his * mind on host distances. It might change it on the node that came/left * but also on other nodes (for instance, if a node dies, another * previously ignored node may be now considered). * * This method ensures that all hosts for which a pool should exist * have one, and hosts that shouldn't don't. */ private void updateCreatedPools() { for (Host h : cluster.getMetadata().allHosts()) { HostDistance dist = loadBalancingPolicy().distance(h); HostConnectionPool pool = pools.get(h); if (pool == null) { if (dist != HostDistance.IGNORED && h.getMonitor().isUp()) addOrRenewPool(h); } else if (dist != pool.hostDistance) { if (dist == HostDistance.IGNORED) { removePool(h); } else { pool.hostDistance = dist; } } } }
public void onDown(Host host) { loadBalancer.onDown(host); HostConnectionPool pool = pools.remove(host); // This should not be necessary but it's harmless if (pool != null) pool.shutdown(); // If we've remove a host, the loadBalancer is allowed to change his mind on host distances. for (Host h : cluster.getMetadata().allHosts()) { if (!h.getMonitor().isUp()) continue; HostDistance dist = loadBalancer.distance(h); if (dist != HostDistance.IGNORED) { HostConnectionPool p = pools.get(h); if (p == null) addHost(host); else p.hostDistance = dist; } } }
private Connection waitForConnection(long timeout, TimeUnit unit) throws ConnectionException, TimeoutException { long start = System.nanoTime(); long remaining = timeout; do { try { awaitAvailableConnection(remaining, unit); } catch (InterruptedException e) { Thread.currentThread().interrupt(); // If we're interrupted fine, check if there is a connection available but stop waiting // otherwise timeout = 0; // this will make us stop the loop if we don't get a connection right away } if (isShutdown()) throw new ConnectionException(host.getAddress(), "Pool is shutdown"); int minInFlight = Integer.MAX_VALUE; Connection leastBusy = null; for (Connection connection : connections) { int inFlight = connection.inFlight.get(); if (inFlight < minInFlight) { minInFlight = inFlight; leastBusy = connection; } } while (true) { int inFlight = leastBusy.inFlight.get(); if (inFlight >= Connection.MAX_STREAM_PER_CONNECTION) break; if (leastBusy.inFlight.compareAndSet(inFlight, inFlight + 1)) return leastBusy; } remaining = timeout - Cluster.timeSince(start, unit); } while (remaining > 0); throw new TimeoutException(); }