private void maybeSpawnNewConnection() { while (true) { int inCreation = scheduledForCreation.get(); if (inCreation >= MAX_SIMULTANEOUS_CREATION) return; if (scheduledForCreation.compareAndSet(inCreation, inCreation + 1)) break; } logger.debug("Creating new connection on busy pool to {}", host); manager.executor().submit(newConnectionTask); }
private void close(final Connection connection) { manager .executor() .submit( new Runnable() { @Override public void run() { connection.close(); } }); }
private void replace(final Connection connection) { connections.remove(connection); manager .executor() .submit( new Runnable() { @Override public void run() { connection.close(); addConnectionIfUnderMaximum(); } }); }
// This creates connections if we have less than core connections (if we // have more than core, connection will just get trash when we can). public void ensureCoreConnections() { if (isShutdown()) return; // Note: this process is a bit racy, but it doesn't matter since we're still guaranteed to not // create // more connection than maximum (and if we create more than core connection due to a race but // this isn't // justified by the load, the connection in excess will be quickly trashed anyway) int opened = open.get(); for (int i = opened; i < options().getCoreConnectionsPerHost(hostDistance); i++) { // We don't respect MAX_SIMULTANEOUS_CREATION here because it's only to // protect against creating connection in excess of core too quickly scheduledForCreation.incrementAndGet(); manager.executor().submit(newConnectionTask); } }
public Connection borrowConnection(long timeout, TimeUnit unit) throws ConnectionException, TimeoutException { if (isShutdown.get()) // Note: throwing a ConnectionException is probably fine in practice as it will trigger the // creation of a new host. // That being said, maybe having a specific exception could be cleaner. throw new ConnectionException(host.getAddress(), "Pool is shutdown"); if (connections.isEmpty()) { for (int i = 0; i < options().getCoreConnectionsPerHost(hostDistance); i++) { // We don't respect MAX_SIMULTANEOUS_CREATION here because it's only to // protect against creating connection in excess of core too quickly scheduledForCreation.incrementAndGet(); manager.executor().submit(newConnectionTask); } Connection c = waitForConnection(timeout, unit); c.setKeyspace(manager.poolsState.keyspace); return c; } int minInFlight = Integer.MAX_VALUE; Connection leastBusy = null; for (Connection connection : connections) { int inFlight = connection.inFlight.get(); if (inFlight < minInFlight) { minInFlight = inFlight; leastBusy = connection; } } if (minInFlight >= options().getMaxSimultaneousRequestsPerConnectionThreshold(hostDistance) && connections.size() < options().getMaxConnectionsPerHost(hostDistance)) maybeSpawnNewConnection(); while (true) { int inFlight = leastBusy.inFlight.get(); if (inFlight >= Connection.MAX_STREAM_PER_CONNECTION) { leastBusy = waitForConnection(timeout, unit); break; } if (leastBusy.inFlight.compareAndSet(inFlight, inFlight + 1)) break; } leastBusy.setKeyspace(manager.poolsState.keyspace); return leastBusy; }