what-the-bank/sources/io/grpc/util/RoundRobinLoadBalancer.java

295 lines
13 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package io.grpc.util;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.huawei.hms.support.feature.result.CommonConstant;
import io.grpc.Attributes;
import io.grpc.ConnectivityState;
import io.grpc.ConnectivityStateInfo;
import io.grpc.EquivalentAddressGroup;
import io.grpc.LoadBalancer;
import io.grpc.Status;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
/* loaded from: classes6.dex */
final class RoundRobinLoadBalancer extends LoadBalancer {
private ConnectivityState currentState;
private final LoadBalancer.Helper helper;
static final Attributes.Key<Ref<ConnectivityStateInfo>> STATE_INFO = Attributes.Key.create("state-info");
private static final Status EMPTY_OK = Status.OK.withDescription("no subchannels ready");
private final Map<EquivalentAddressGroup, LoadBalancer.Subchannel> subchannels = new HashMap();
private RoundRobinPicker currentPicker = new EmptyPicker(EMPTY_OK);
private final Random random = new Random();
/* JADX INFO: Access modifiers changed from: package-private */
public RoundRobinLoadBalancer(LoadBalancer.Helper helper) {
this.helper = (LoadBalancer.Helper) Preconditions.checkNotNull(helper, "helper");
}
@Override // io.grpc.LoadBalancer
public final void handleResolvedAddresses(LoadBalancer.ResolvedAddresses resolvedAddresses) {
List<EquivalentAddressGroup> addresses = resolvedAddresses.getAddresses();
Set<EquivalentAddressGroup> keySet = this.subchannels.keySet();
Map<EquivalentAddressGroup, EquivalentAddressGroup> stripAttrs = stripAttrs(addresses);
Set set = setsDifference(keySet, stripAttrs.keySet());
for (Map.Entry<EquivalentAddressGroup, EquivalentAddressGroup> entry : stripAttrs.entrySet()) {
EquivalentAddressGroup key = entry.getKey();
EquivalentAddressGroup value = entry.getValue();
LoadBalancer.Subchannel subchannel = this.subchannels.get(key);
if (subchannel != null) {
subchannel.updateAddresses(Collections.singletonList(value));
} else {
LoadBalancer.Subchannel subchannel2 = (LoadBalancer.Subchannel) Preconditions.checkNotNull(this.helper.createSubchannel(LoadBalancer.CreateSubchannelArgs.newBuilder().setAddresses(value).setAttributes(Attributes.newBuilder().set(STATE_INFO, new Ref(ConnectivityStateInfo.forNonError(ConnectivityState.IDLE))).build()).build()), "subchannel");
subchannel2.start(new LoadBalancer.SubchannelStateListener(this, subchannel2) { // from class: io.grpc.util.RoundRobinLoadBalancer.1
final RoundRobinLoadBalancer this$0;
final LoadBalancer.Subchannel val$subchannel;
{
this.this$0 = this;
this.val$subchannel = subchannel2;
}
@Override // io.grpc.LoadBalancer.SubchannelStateListener
public void onSubchannelState(ConnectivityStateInfo connectivityStateInfo) {
this.this$0.processSubchannelState(this.val$subchannel, connectivityStateInfo);
}
});
this.subchannels.put(key, subchannel2);
subchannel2.requestConnection();
}
}
ArrayList arrayList = new ArrayList();
Iterator it = set.iterator();
while (it.hasNext()) {
arrayList.add(this.subchannels.remove((EquivalentAddressGroup) it.next()));
}
updateBalancingState();
Iterator it2 = arrayList.iterator();
while (it2.hasNext()) {
shutdownSubchannel((LoadBalancer.Subchannel) it2.next());
}
}
@Override // io.grpc.LoadBalancer
public final void handleNameResolutionError(Status status) {
if (this.currentState != ConnectivityState.READY) {
updateBalancingState(ConnectivityState.TRANSIENT_FAILURE, new EmptyPicker(status));
}
}
/* JADX INFO: Access modifiers changed from: private */
/* JADX WARN: Multi-variable type inference failed */
public void processSubchannelState(LoadBalancer.Subchannel subchannel, ConnectivityStateInfo connectivityStateInfo) {
if (this.subchannels.get(stripAttrs(subchannel.getAddresses())) != subchannel) {
return;
}
if (connectivityStateInfo.getState() == ConnectivityState.TRANSIENT_FAILURE || connectivityStateInfo.getState() == ConnectivityState.IDLE) {
this.helper.refreshNameResolution();
}
if (connectivityStateInfo.getState() == ConnectivityState.IDLE) {
subchannel.requestConnection();
}
Ref<ConnectivityStateInfo> subchannelStateInfoRef = getSubchannelStateInfoRef(subchannel);
if (subchannelStateInfoRef.value.getState().equals(ConnectivityState.TRANSIENT_FAILURE) && (connectivityStateInfo.getState().equals(ConnectivityState.CONNECTING) || connectivityStateInfo.getState().equals(ConnectivityState.IDLE))) {
return;
}
subchannelStateInfoRef.value = connectivityStateInfo;
updateBalancingState();
}
/* JADX WARN: Type inference failed for: r0v1, types: [T, io.grpc.ConnectivityStateInfo] */
private void shutdownSubchannel(LoadBalancer.Subchannel subchannel) {
subchannel.shutdown();
getSubchannelStateInfoRef(subchannel).value = ConnectivityStateInfo.forNonError(ConnectivityState.SHUTDOWN);
}
@Override // io.grpc.LoadBalancer
public final void shutdown() {
Iterator<LoadBalancer.Subchannel> it = getSubchannels().iterator();
while (it.hasNext()) {
shutdownSubchannel(it.next());
}
this.subchannels.clear();
}
private void updateBalancingState() {
List<LoadBalancer.Subchannel> filterNonFailingSubchannels = filterNonFailingSubchannels(getSubchannels());
if (filterNonFailingSubchannels.isEmpty()) {
Status status = EMPTY_OK;
Iterator<LoadBalancer.Subchannel> it = getSubchannels().iterator();
boolean z = false;
while (it.hasNext()) {
ConnectivityStateInfo connectivityStateInfo = getSubchannelStateInfoRef(it.next()).value;
if (connectivityStateInfo.getState() == ConnectivityState.CONNECTING || connectivityStateInfo.getState() == ConnectivityState.IDLE) {
z = true;
}
if (status == EMPTY_OK || !status.isOk()) {
status = connectivityStateInfo.getStatus();
}
}
updateBalancingState(z ? ConnectivityState.CONNECTING : ConnectivityState.TRANSIENT_FAILURE, new EmptyPicker(status));
return;
}
updateBalancingState(ConnectivityState.READY, new ReadyPicker(filterNonFailingSubchannels, this.random.nextInt(filterNonFailingSubchannels.size())));
}
private void updateBalancingState(ConnectivityState connectivityState, RoundRobinPicker roundRobinPicker) {
if (connectivityState == this.currentState && roundRobinPicker.isEquivalentTo(this.currentPicker)) {
return;
}
this.helper.updateBalancingState(connectivityState, roundRobinPicker);
this.currentState = connectivityState;
this.currentPicker = roundRobinPicker;
}
private static List<LoadBalancer.Subchannel> filterNonFailingSubchannels(Collection<LoadBalancer.Subchannel> collection) {
ArrayList arrayList = new ArrayList(collection.size());
for (LoadBalancer.Subchannel subchannel : collection) {
if (isReady(subchannel)) {
arrayList.add(subchannel);
}
}
return arrayList;
}
private static Map<EquivalentAddressGroup, EquivalentAddressGroup> stripAttrs(List<EquivalentAddressGroup> list) {
HashMap hashMap = new HashMap(list.size() << 1);
for (EquivalentAddressGroup equivalentAddressGroup : list) {
hashMap.put(stripAttrs(equivalentAddressGroup), equivalentAddressGroup);
}
return hashMap;
}
private static EquivalentAddressGroup stripAttrs(EquivalentAddressGroup equivalentAddressGroup) {
return new EquivalentAddressGroup(equivalentAddressGroup.getAddresses());
}
final Collection<LoadBalancer.Subchannel> getSubchannels() {
return this.subchannels.values();
}
private static Ref<ConnectivityStateInfo> getSubchannelStateInfoRef(LoadBalancer.Subchannel subchannel) {
return (Ref) Preconditions.checkNotNull((Ref) subchannel.getAttributes().get(STATE_INFO), "STATE_INFO");
}
static boolean isReady(LoadBalancer.Subchannel subchannel) {
return getSubchannelStateInfoRef(subchannel).value.getState() == ConnectivityState.READY;
}
private static <T> Set<T> setsDifference(Set<T> set, Set<T> set2) {
HashSet hashSet = new HashSet(set);
hashSet.removeAll(set2);
return hashSet;
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public static abstract class RoundRobinPicker extends LoadBalancer.SubchannelPicker {
abstract boolean isEquivalentTo(RoundRobinPicker roundRobinPicker);
private RoundRobinPicker() {
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public static final class ReadyPicker extends RoundRobinPicker {
private static final AtomicIntegerFieldUpdater<ReadyPicker> indexUpdater = AtomicIntegerFieldUpdater.newUpdater(ReadyPicker.class, "index");
private volatile int index;
private final List<LoadBalancer.Subchannel> list;
ReadyPicker(List<LoadBalancer.Subchannel> list, int i) {
super();
Preconditions.checkArgument(!list.isEmpty(), "empty list");
this.list = list;
this.index = i - 1;
}
@Override // io.grpc.LoadBalancer.SubchannelPicker
public final LoadBalancer.PickResult pickSubchannel(LoadBalancer.PickSubchannelArgs pickSubchannelArgs) {
return LoadBalancer.PickResult.withSubchannel(nextSubchannel());
}
public final String toString() {
return MoreObjects.toStringHelper((Class<?>) ReadyPicker.class).add("list", this.list).toString();
}
private LoadBalancer.Subchannel nextSubchannel() {
int size = this.list.size();
AtomicIntegerFieldUpdater<ReadyPicker> atomicIntegerFieldUpdater = indexUpdater;
int incrementAndGet = atomicIntegerFieldUpdater.incrementAndGet(this);
if (incrementAndGet >= size) {
int i = incrementAndGet % size;
atomicIntegerFieldUpdater.compareAndSet(this, incrementAndGet, i);
incrementAndGet = i;
}
return this.list.get(incrementAndGet);
}
@Override // io.grpc.util.RoundRobinLoadBalancer.RoundRobinPicker
final boolean isEquivalentTo(RoundRobinPicker roundRobinPicker) {
if (!(roundRobinPicker instanceof ReadyPicker)) {
return false;
}
ReadyPicker readyPicker = (ReadyPicker) roundRobinPicker;
return readyPicker == this || (this.list.size() == readyPicker.list.size() && new HashSet(this.list).containsAll(readyPicker.list));
}
final List<LoadBalancer.Subchannel> getList() {
return this.list;
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public static final class EmptyPicker extends RoundRobinPicker {
private final Status status;
EmptyPicker(Status status) {
super();
this.status = (Status) Preconditions.checkNotNull(status, CommonConstant.KEY_STATUS);
}
@Override // io.grpc.LoadBalancer.SubchannelPicker
public final LoadBalancer.PickResult pickSubchannel(LoadBalancer.PickSubchannelArgs pickSubchannelArgs) {
return this.status.isOk() ? LoadBalancer.PickResult.withNoResult() : LoadBalancer.PickResult.withError(this.status);
}
@Override // io.grpc.util.RoundRobinLoadBalancer.RoundRobinPicker
final boolean isEquivalentTo(RoundRobinPicker roundRobinPicker) {
if (roundRobinPicker instanceof EmptyPicker) {
EmptyPicker emptyPicker = (EmptyPicker) roundRobinPicker;
if (Objects.equal(this.status, emptyPicker.status) || (this.status.isOk() && emptyPicker.status.isOk())) {
return true;
}
}
return false;
}
public final String toString() {
return MoreObjects.toStringHelper((Class<?>) EmptyPicker.class).add(CommonConstant.KEY_STATUS, this.status).toString();
}
}
/* JADX INFO: Access modifiers changed from: package-private */
/* loaded from: classes6.dex */
public static final class Ref<T> {
T value;
Ref(T t) {
this.value = t;
}
}
}