in grpc-gcp/src/main/java/com/google/cloud/grpc/GcpManagedChannel.java [1198:1268]
private ChannelRef pickLeastBusyChannel(boolean forFallback) {
ChannelRef first = createFirstChannel();
if (first != null) {
return first;
}
// Pick the least busy channel and the least busy ready and not overloaded channel (this could
// be the same channel or different or no channel).
ChannelRef channelCandidate = channelRefs.get(0);
int minStreams = channelCandidate.getActiveStreamsCount();
ChannelRef readyCandidate = null;
int readyMinStreams = Integer.MAX_VALUE;
for (ChannelRef channelRef : channelRefs) {
int cnt = channelRef.getActiveStreamsCount();
if (cnt < minStreams) {
minStreams = cnt;
channelCandidate = channelRef;
}
if (cnt < readyMinStreams
&& !fallbackMap.containsKey(channelRef.getId())
&& channelRef.getActiveStreamsCount() < DEFAULT_MAX_STREAM) {
readyMinStreams = cnt;
readyCandidate = channelRef;
}
}
if (!fallbackEnabled) {
if (channelRefs.size() < maxSize && minStreams >= maxConcurrentStreamsLowWatermark) {
ChannelRef newChannel = tryCreateNewChannel();
if (newChannel != null) {
return newChannel;
}
}
return channelCandidate;
}
if (channelRefs.size() < maxSize && readyMinStreams >= maxConcurrentStreamsLowWatermark) {
ChannelRef newChannel = tryCreateNewChannel();
if (newChannel != null) {
if (!forFallback && readyCandidate == null) {
if (logger.isLoggable(Level.FINEST)) {
logger.finest(log("Fallback to newly created channel %d", newChannel.getId()));
}
fallbacksSucceeded.incrementAndGet();
}
return newChannel;
}
}
if (readyCandidate != null) {
if (!forFallback && readyCandidate.getId() != channelCandidate.getId()) {
if (logger.isLoggable(Level.FINEST)) {
logger.finest(
log(
"Picking fallback channel: %d -> %d",
channelCandidate.getId(), readyCandidate.getId()));
}
fallbacksSucceeded.incrementAndGet();
}
return readyCandidate;
}
if (!forFallback) {
if (logger.isLoggable(Level.FINEST)) {
logger.finest(log("Failed to find fallback for channel %d", channelCandidate.getId()));
}
fallbacksFailed.incrementAndGet();
}
return channelCandidate;
}