in httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java [311:384]
private boolean processPendingRequest(final LeaseRequest<T, C> request) {
final T route = request.getRoute();
final Object state = request.getState();
final Deadline deadline = request.getDeadline();
if (deadline.isExpired()) {
request.failed(DeadlineTimeoutException.from(deadline));
return false;
}
final PerRoutePool<T, C> pool = getPool(route);
PoolEntry<T, C> entry;
for (;;) {
entry = pool.getFree(state);
if (entry == null) {
break;
}
if (entry.getExpiryDeadline().isExpired()) {
entry.discardConnection(CloseMode.GRACEFUL);
this.available.remove(entry);
pool.free(entry, false);
} else {
break;
}
}
if (entry != null) {
this.available.remove(entry);
this.leased.add(entry);
request.completed(entry);
if (this.connPoolListener != null) {
this.connPoolListener.onLease(entry.getRoute(), this);
}
return true;
}
// New connection is needed
final int maxPerRoute = getMax(route);
// Shrink the pool prior to allocating a new connection
final int excess = Math.max(0, pool.getAllocatedCount() + 1 - maxPerRoute);
if (excess > 0) {
for (int i = 0; i < excess; i++) {
final PoolEntry<T, C> lastUsed = pool.getLastUsed();
if (lastUsed == null) {
break;
}
lastUsed.discardConnection(CloseMode.GRACEFUL);
this.available.remove(lastUsed);
pool.remove(lastUsed);
}
}
if (pool.getAllocatedCount() < maxPerRoute) {
final int freeCapacity = Math.max(this.maxTotal - this.leased.size(), 0);
if (freeCapacity == 0) {
return false;
}
final int totalAvailable = this.available.size();
if (totalAvailable > freeCapacity - 1) {
final PoolEntry<T, C> lastUsed = this.available.removeLast();
lastUsed.discardConnection(CloseMode.GRACEFUL);
final PerRoutePool<T, C> otherpool = getPool(lastUsed.getRoute());
otherpool.remove(lastUsed);
}
entry = pool.createEntry(this.timeToLive);
this.leased.add(entry);
request.completed(entry);
if (this.connPoolListener != null) {
this.connPoolListener.onLease(entry.getRoute(), this);
}
return true;
}
return false;
}