1384 lines
56 KiB
Java
1384 lines
56 KiB
Java
package io.grpc.internal;
|
|
|
|
import com.google.common.base.Objects;
|
|
import com.google.common.base.Preconditions;
|
|
import com.kofax.kmc.kut.utilities.IpLibUtil;
|
|
import io.grpc.Attributes;
|
|
import io.grpc.ClientStreamTracer;
|
|
import io.grpc.Compressor;
|
|
import io.grpc.Deadline;
|
|
import io.grpc.DecompressorRegistry;
|
|
import io.grpc.Metadata;
|
|
import io.grpc.MethodDescriptor;
|
|
import io.grpc.Status;
|
|
import io.grpc.SynchronizationContext;
|
|
import io.grpc.internal.ClientStreamListener;
|
|
import io.grpc.internal.StreamListener;
|
|
import java.io.InputStream;
|
|
import java.lang.Thread;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.Future;
|
|
import java.util.concurrent.ScheduledExecutorService;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public abstract class RetriableStream<ReqT> implements ClientStream {
|
|
private final Executor callExecutor;
|
|
private Status cancellationStatus;
|
|
private final long channelBufferLimit;
|
|
private final ChannelBufferMeter channelBufferUsed;
|
|
private final Metadata headers;
|
|
private final HedgingPolicy hedgingPolicy;
|
|
private boolean isClosed;
|
|
private final boolean isHedging;
|
|
private ClientStreamListener masterListener;
|
|
private final MethodDescriptor<ReqT, ?> method;
|
|
private long nextBackoffIntervalNanos;
|
|
private final long perRpcBufferLimit;
|
|
private long perRpcBufferUsed;
|
|
private final RetryPolicy retryPolicy;
|
|
private final ScheduledExecutorService scheduledExecutorService;
|
|
private FutureCanceller scheduledHedging;
|
|
private FutureCanceller scheduledRetry;
|
|
private final Throttle throttle;
|
|
static final Metadata.Key<String> GRPC_PREVIOUS_RPC_ATTEMPTS = Metadata.Key.of("grpc-previous-rpc-attempts", Metadata.ASCII_STRING_MARSHALLER);
|
|
static final Metadata.Key<String> GRPC_RETRY_PUSHBACK_MS = Metadata.Key.of("grpc-retry-pushback-ms", Metadata.ASCII_STRING_MARSHALLER);
|
|
private static final Status CANCELLED_BECAUSE_COMMITTED = Status.CANCELLED.withDescription("Stream thrown away because RetriableStream committed");
|
|
private static Random random = new Random();
|
|
private final Executor listenerSerializeExecutor = new SynchronizationContext(new Thread.UncaughtExceptionHandler(this) { // from class: io.grpc.internal.RetriableStream.1
|
|
final RetriableStream this$0;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
}
|
|
|
|
@Override // java.lang.Thread.UncaughtExceptionHandler
|
|
public void uncaughtException(Thread thread, Throwable th) {
|
|
throw Status.fromThrowable(th).withDescription("Uncaught exception in the SynchronizationContext. Re-thrown.").asRuntimeException();
|
|
}
|
|
});
|
|
private final Object lock = new Object();
|
|
private final InsightBuilder closedSubstreamsInsight = new InsightBuilder();
|
|
private volatile State state = new State(new ArrayList(8), Collections.emptyList(), null, null, false, false, false, 0);
|
|
private final AtomicBoolean noMoreTransparentRetry = new AtomicBoolean();
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public interface BufferEntry {
|
|
void runWith(Substream substream);
|
|
}
|
|
|
|
abstract ClientStream newSubstream(Metadata metadata, ClientStreamTracer.Factory factory, int i, boolean z);
|
|
|
|
abstract void postCommit();
|
|
|
|
abstract Status prestart();
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public RetriableStream(MethodDescriptor<ReqT, ?> methodDescriptor, Metadata metadata, ChannelBufferMeter channelBufferMeter, long j, long j2, Executor executor, ScheduledExecutorService scheduledExecutorService, RetryPolicy retryPolicy, HedgingPolicy hedgingPolicy, Throttle throttle) {
|
|
this.method = methodDescriptor;
|
|
this.channelBufferUsed = channelBufferMeter;
|
|
this.perRpcBufferLimit = j;
|
|
this.channelBufferLimit = j2;
|
|
this.callExecutor = executor;
|
|
this.scheduledExecutorService = scheduledExecutorService;
|
|
this.headers = metadata;
|
|
this.retryPolicy = retryPolicy;
|
|
if (retryPolicy != null) {
|
|
this.nextBackoffIntervalNanos = retryPolicy.initialBackoffNanos;
|
|
}
|
|
this.hedgingPolicy = hedgingPolicy;
|
|
Preconditions.checkArgument(retryPolicy == null || hedgingPolicy == null, "Should not provide both retryPolicy and hedgingPolicy");
|
|
this.isHedging = hedgingPolicy != null;
|
|
this.throttle = throttle;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public Runnable commit(Substream substream) {
|
|
Future<?> future;
|
|
Future<?> future2;
|
|
synchronized (this.lock) {
|
|
if (this.state.winningSubstream != null) {
|
|
return null;
|
|
}
|
|
Collection<Substream> collection = this.state.drainedSubstreams;
|
|
this.state = this.state.committed(substream);
|
|
this.channelBufferUsed.addAndGet(-this.perRpcBufferUsed);
|
|
FutureCanceller futureCanceller = this.scheduledRetry;
|
|
if (futureCanceller != null) {
|
|
Future<?> markCancelled = futureCanceller.markCancelled();
|
|
this.scheduledRetry = null;
|
|
future = markCancelled;
|
|
} else {
|
|
future = null;
|
|
}
|
|
FutureCanceller futureCanceller2 = this.scheduledHedging;
|
|
if (futureCanceller2 != null) {
|
|
Future<?> markCancelled2 = futureCanceller2.markCancelled();
|
|
this.scheduledHedging = null;
|
|
future2 = markCancelled2;
|
|
} else {
|
|
future2 = null;
|
|
}
|
|
return new Runnable(this, collection, substream, future, future2) { // from class: io.grpc.internal.RetriableStream.1CommitTask
|
|
final RetriableStream this$0;
|
|
final Future val$hedgingFuture;
|
|
final Future val$retryFuture;
|
|
final Collection val$savedDrainedSubstreams;
|
|
final Substream val$winningSubstream;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$savedDrainedSubstreams = collection;
|
|
this.val$winningSubstream = substream;
|
|
this.val$retryFuture = future;
|
|
this.val$hedgingFuture = future2;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
for (Substream substream2 : this.val$savedDrainedSubstreams) {
|
|
if (substream2 != this.val$winningSubstream) {
|
|
substream2.stream.cancel(RetriableStream.CANCELLED_BECAUSE_COMMITTED);
|
|
}
|
|
}
|
|
Future future3 = this.val$retryFuture;
|
|
if (future3 != null) {
|
|
future3.cancel(false);
|
|
}
|
|
Future future4 = this.val$hedgingFuture;
|
|
if (future4 != null) {
|
|
future4.cancel(false);
|
|
}
|
|
this.this$0.postCommit();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void commitAndRun(Substream substream) {
|
|
Runnable commit = commit(substream);
|
|
if (commit != null) {
|
|
commit.run();
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public Substream createSubstream(int i, boolean z) {
|
|
Substream substream = new Substream(i);
|
|
substream.stream = newSubstream(updateHeaders(this.headers, i), new ClientStreamTracer.Factory(this, new BufferSizeTracer(this, substream)) { // from class: io.grpc.internal.RetriableStream.2
|
|
final RetriableStream this$0;
|
|
final ClientStreamTracer val$bufferSizeTracer;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$bufferSizeTracer = r2;
|
|
}
|
|
|
|
@Override // io.grpc.ClientStreamTracer.Factory
|
|
public ClientStreamTracer newClientStreamTracer(ClientStreamTracer.StreamInfo streamInfo, Metadata metadata) {
|
|
return this.val$bufferSizeTracer;
|
|
}
|
|
}, i, z);
|
|
return substream;
|
|
}
|
|
|
|
final Metadata updateHeaders(Metadata metadata, int i) {
|
|
Metadata metadata2 = new Metadata();
|
|
metadata2.merge(metadata);
|
|
if (i > 0) {
|
|
metadata2.put(GRPC_PREVIOUS_RPC_ATTEMPTS, String.valueOf(i));
|
|
}
|
|
return metadata2;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
/* JADX WARN: Code restructure failed: missing block: B:13:0x0037, code lost:
|
|
|
|
if (r1 == null) goto L28;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:14:0x0039, code lost:
|
|
|
|
r8.listenerSerializeExecutor.execute(r1);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:15:0x003e, code lost:
|
|
|
|
return;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:17:0x003f, code lost:
|
|
|
|
r0 = r9.stream;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:18:0x0045, code lost:
|
|
|
|
if (r8.state.winningSubstream != r9) goto L31;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:19:0x0047, code lost:
|
|
|
|
r9 = r8.cancellationStatus;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:20:0x004c, code lost:
|
|
|
|
r0.cancel(r9);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:21:0x004f, code lost:
|
|
|
|
return;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:22:0x004a, code lost:
|
|
|
|
r9 = io.grpc.internal.RetriableStream.CANCELLED_BECAUSE_COMMITTED;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:36:0x007d, code lost:
|
|
|
|
r2 = r3.iterator();
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:38:0x0085, code lost:
|
|
|
|
if (r2.hasNext() == false) goto L67;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:39:0x0087, code lost:
|
|
|
|
r4 = (io.grpc.internal.RetriableStream.BufferEntry) r2.next();
|
|
r4.runWith(r9);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:40:0x0092, code lost:
|
|
|
|
if ((r4 instanceof io.grpc.internal.RetriableStream.StartEntry) == false) goto L50;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:41:0x0094, code lost:
|
|
|
|
r0 = true;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:42:0x0095, code lost:
|
|
|
|
if (r0 == false) goto L72;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:44:0x0097, code lost:
|
|
|
|
r4 = r8.state;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:45:0x009b, code lost:
|
|
|
|
if (r4.winningSubstream == null) goto L55;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:47:0x009f, code lost:
|
|
|
|
if (r4.winningSubstream != r9) goto L68;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:51:0x00a3, code lost:
|
|
|
|
if (r4.cancelled == false) goto L73;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:62:0x0023, code lost:
|
|
|
|
r8.state = r5.substreamDrained(r9);
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:63:0x002d, code lost:
|
|
|
|
if (isReady() != false) goto L23;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:65:0x0030, code lost:
|
|
|
|
return;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:66:0x0031, code lost:
|
|
|
|
r1 = new io.grpc.internal.RetriableStream.AnonymousClass3(r8);
|
|
*/
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct add '--show-bad-code' argument
|
|
*/
|
|
public void drain(io.grpc.internal.RetriableStream.Substream r9) {
|
|
/*
|
|
r8 = this;
|
|
r0 = 0
|
|
r1 = 0
|
|
r2 = r0
|
|
r3 = r1
|
|
L4:
|
|
java.lang.Object r4 = r8.lock
|
|
monitor-enter(r4)
|
|
io.grpc.internal.RetriableStream$State r5 = r8.state // Catch: java.lang.Throwable -> La8
|
|
if (r0 == 0) goto L1b
|
|
io.grpc.internal.RetriableStream$Substream r6 = r5.winningSubstream // Catch: java.lang.Throwable -> La8
|
|
if (r6 == 0) goto L15
|
|
io.grpc.internal.RetriableStream$Substream r6 = r5.winningSubstream // Catch: java.lang.Throwable -> La8
|
|
if (r6 == r9) goto L15
|
|
monitor-exit(r4)
|
|
goto L37
|
|
L15:
|
|
boolean r6 = r5.cancelled // Catch: java.lang.Throwable -> La8
|
|
if (r6 == 0) goto L1b
|
|
monitor-exit(r4)
|
|
goto L37
|
|
L1b:
|
|
java.util.List<io.grpc.internal.RetriableStream$BufferEntry> r6 = r5.buffer // Catch: java.lang.Throwable -> La8
|
|
int r6 = r6.size() // Catch: java.lang.Throwable -> La8
|
|
if (r2 != r6) goto L50
|
|
io.grpc.internal.RetriableStream$State r0 = r5.substreamDrained(r9) // Catch: java.lang.Throwable -> La8
|
|
r8.state = r0 // Catch: java.lang.Throwable -> La8
|
|
boolean r0 = r8.isReady() // Catch: java.lang.Throwable -> La8
|
|
if (r0 != 0) goto L31
|
|
monitor-exit(r4)
|
|
return
|
|
L31:
|
|
io.grpc.internal.RetriableStream$3 r1 = new io.grpc.internal.RetriableStream$3 // Catch: java.lang.Throwable -> La8
|
|
r1.<init>(r8) // Catch: java.lang.Throwable -> La8
|
|
monitor-exit(r4)
|
|
L37:
|
|
if (r1 == 0) goto L3f
|
|
java.util.concurrent.Executor r9 = r8.listenerSerializeExecutor
|
|
r9.execute(r1)
|
|
return
|
|
L3f:
|
|
io.grpc.internal.ClientStream r0 = r9.stream
|
|
io.grpc.internal.RetriableStream$State r1 = r8.state
|
|
io.grpc.internal.RetriableStream$Substream r1 = r1.winningSubstream
|
|
if (r1 != r9) goto L4a
|
|
io.grpc.Status r9 = r8.cancellationStatus
|
|
goto L4c
|
|
L4a:
|
|
io.grpc.Status r9 = io.grpc.internal.RetriableStream.CANCELLED_BECAUSE_COMMITTED
|
|
L4c:
|
|
r0.cancel(r9)
|
|
return
|
|
L50:
|
|
boolean r6 = r9.closed // Catch: java.lang.Throwable -> La8
|
|
if (r6 == 0) goto L56
|
|
monitor-exit(r4)
|
|
return
|
|
L56:
|
|
int r6 = r2 + 128
|
|
java.util.List<io.grpc.internal.RetriableStream$BufferEntry> r7 = r5.buffer // Catch: java.lang.Throwable -> La8
|
|
int r7 = r7.size() // Catch: java.lang.Throwable -> La8
|
|
int r6 = java.lang.Math.min(r6, r7) // Catch: java.lang.Throwable -> La8
|
|
if (r3 != 0) goto L70
|
|
java.util.ArrayList r3 = new java.util.ArrayList // Catch: java.lang.Throwable -> La8
|
|
java.util.List<io.grpc.internal.RetriableStream$BufferEntry> r5 = r5.buffer // Catch: java.lang.Throwable -> La8
|
|
java.util.List r2 = r5.subList(r2, r6) // Catch: java.lang.Throwable -> La8
|
|
r3.<init>(r2) // Catch: java.lang.Throwable -> La8
|
|
goto L7c
|
|
L70:
|
|
r3.clear() // Catch: java.lang.Throwable -> La8
|
|
java.util.List<io.grpc.internal.RetriableStream$BufferEntry> r5 = r5.buffer // Catch: java.lang.Throwable -> La8
|
|
java.util.List r2 = r5.subList(r2, r6) // Catch: java.lang.Throwable -> La8
|
|
r3.addAll(r2) // Catch: java.lang.Throwable -> La8
|
|
L7c:
|
|
monitor-exit(r4)
|
|
java.util.Iterator r2 = r3.iterator()
|
|
L81:
|
|
boolean r4 = r2.hasNext()
|
|
if (r4 == 0) goto La5
|
|
java.lang.Object r4 = r2.next()
|
|
io.grpc.internal.RetriableStream$BufferEntry r4 = (io.grpc.internal.RetriableStream.BufferEntry) r4
|
|
r4.runWith(r9)
|
|
boolean r4 = r4 instanceof io.grpc.internal.RetriableStream.StartEntry
|
|
if (r4 == 0) goto L95
|
|
r0 = 1
|
|
L95:
|
|
if (r0 == 0) goto L81
|
|
io.grpc.internal.RetriableStream$State r4 = r8.state
|
|
io.grpc.internal.RetriableStream$Substream r5 = r4.winningSubstream
|
|
if (r5 == 0) goto La1
|
|
io.grpc.internal.RetriableStream$Substream r5 = r4.winningSubstream
|
|
if (r5 != r9) goto La5
|
|
La1:
|
|
boolean r4 = r4.cancelled
|
|
if (r4 == 0) goto L81
|
|
La5:
|
|
r2 = r6
|
|
goto L4
|
|
La8:
|
|
r9 = move-exception
|
|
monitor-exit(r4)
|
|
throw r9
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: io.grpc.internal.RetriableStream.drain(io.grpc.internal.RetriableStream$Substream):void");
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public class StartEntry implements BufferEntry {
|
|
final RetriableStream this$0;
|
|
|
|
StartEntry(RetriableStream retriableStream) {
|
|
this.this$0 = retriableStream;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.start(new Sublistener(this.this$0, substream));
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void start(ClientStreamListener clientStreamListener) {
|
|
FutureCanceller futureCanceller;
|
|
Throttle throttle;
|
|
this.masterListener = clientStreamListener;
|
|
Status prestart = prestart();
|
|
if (prestart != null) {
|
|
cancel(prestart);
|
|
return;
|
|
}
|
|
synchronized (this.lock) {
|
|
this.state.buffer.add(new StartEntry(this));
|
|
}
|
|
Substream createSubstream = createSubstream(0, false);
|
|
if (this.isHedging) {
|
|
synchronized (this.lock) {
|
|
this.state = this.state.addActiveHedge(createSubstream);
|
|
if (hasPotentialHedging(this.state) && ((throttle = this.throttle) == null || throttle.isAboveThreshold())) {
|
|
futureCanceller = new FutureCanceller(this.lock);
|
|
this.scheduledHedging = futureCanceller;
|
|
} else {
|
|
futureCanceller = null;
|
|
}
|
|
}
|
|
if (futureCanceller != null) {
|
|
futureCanceller.setFuture(this.scheduledExecutorService.schedule(new HedgingRunnable(this, futureCanceller), this.hedgingPolicy.hedgingDelayNanos, TimeUnit.NANOSECONDS));
|
|
}
|
|
}
|
|
drain(createSubstream);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void pushbackHedging(Integer num) {
|
|
if (num == null) {
|
|
return;
|
|
}
|
|
if (num.intValue() < 0) {
|
|
freezeHedging();
|
|
return;
|
|
}
|
|
synchronized (this.lock) {
|
|
FutureCanceller futureCanceller = this.scheduledHedging;
|
|
if (futureCanceller == null) {
|
|
return;
|
|
}
|
|
Future<?> markCancelled = futureCanceller.markCancelled();
|
|
FutureCanceller futureCanceller2 = new FutureCanceller(this.lock);
|
|
this.scheduledHedging = futureCanceller2;
|
|
if (markCancelled != null) {
|
|
markCancelled.cancel(false);
|
|
}
|
|
futureCanceller2.setFuture(this.scheduledExecutorService.schedule(new HedgingRunnable(this, futureCanceller2), num.intValue(), TimeUnit.MILLISECONDS));
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public final class HedgingRunnable implements Runnable {
|
|
final FutureCanceller scheduledHedgingRef;
|
|
final RetriableStream this$0;
|
|
|
|
HedgingRunnable(RetriableStream retriableStream, FutureCanceller futureCanceller) {
|
|
this.this$0 = retriableStream;
|
|
this.scheduledHedgingRef = futureCanceller;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public final void run() {
|
|
this.this$0.callExecutor.execute(new Runnable(this) { // from class: io.grpc.internal.RetriableStream.HedgingRunnable.1
|
|
final HedgingRunnable this$1;
|
|
|
|
{
|
|
this.this$1 = this;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
FutureCanceller futureCanceller;
|
|
boolean z = false;
|
|
Substream createSubstream = this.this$1.this$0.createSubstream(this.this$1.this$0.state.hedgingAttemptCount, false);
|
|
synchronized (this.this$1.this$0.lock) {
|
|
futureCanceller = null;
|
|
if (this.this$1.scheduledHedgingRef.isCancelled()) {
|
|
z = true;
|
|
} else {
|
|
this.this$1.this$0.state = this.this$1.this$0.state.addActiveHedge(createSubstream);
|
|
if (this.this$1.this$0.hasPotentialHedging(this.this$1.this$0.state) && (this.this$1.this$0.throttle == null || this.this$1.this$0.throttle.isAboveThreshold())) {
|
|
RetriableStream retriableStream = this.this$1.this$0;
|
|
futureCanceller = new FutureCanceller(this.this$1.this$0.lock);
|
|
retriableStream.scheduledHedging = futureCanceller;
|
|
} else {
|
|
this.this$1.this$0.state = this.this$1.this$0.state.freezeHedging();
|
|
this.this$1.this$0.scheduledHedging = null;
|
|
}
|
|
}
|
|
}
|
|
if (!z) {
|
|
if (futureCanceller != null) {
|
|
futureCanceller.setFuture(this.this$1.this$0.scheduledExecutorService.schedule(new HedgingRunnable(this.this$1.this$0, futureCanceller), this.this$1.this$0.hedgingPolicy.hedgingDelayNanos, TimeUnit.NANOSECONDS));
|
|
}
|
|
this.this$1.this$0.drain(createSubstream);
|
|
return;
|
|
}
|
|
createSubstream.stream.cancel(Status.CANCELLED.withDescription("Unneeded hedging"));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void cancel(Status status) {
|
|
Substream substream;
|
|
Substream substream2 = new Substream(0);
|
|
substream2.stream = new NoopClientStream();
|
|
Runnable commit = commit(substream2);
|
|
if (commit != null) {
|
|
commit.run();
|
|
this.listenerSerializeExecutor.execute(new Runnable(this, status) { // from class: io.grpc.internal.RetriableStream.4
|
|
final RetriableStream this$0;
|
|
final Status val$reason;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$reason = status;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
this.this$0.isClosed = true;
|
|
this.this$0.masterListener.closed(this.val$reason, ClientStreamListener.RpcProgress.PROCESSED, new Metadata());
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
synchronized (this.lock) {
|
|
if (this.state.drainedSubstreams.contains(this.state.winningSubstream)) {
|
|
substream = this.state.winningSubstream;
|
|
} else {
|
|
this.cancellationStatus = status;
|
|
substream = null;
|
|
}
|
|
this.state = this.state.cancelled();
|
|
}
|
|
if (substream != null) {
|
|
substream.stream.cancel(status);
|
|
}
|
|
}
|
|
|
|
private void delayOrExecute(BufferEntry bufferEntry) {
|
|
Collection<Substream> collection;
|
|
synchronized (this.lock) {
|
|
if (!this.state.passThrough) {
|
|
this.state.buffer.add(bufferEntry);
|
|
}
|
|
collection = this.state.drainedSubstreams;
|
|
}
|
|
Iterator<Substream> it = collection.iterator();
|
|
while (it.hasNext()) {
|
|
bufferEntry.runWith(it.next());
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final void writeMessage(InputStream inputStream) {
|
|
throw new IllegalStateException("RetriableStream.writeMessage() should not be called directly");
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public final void sendMessage(ReqT reqt) {
|
|
State state = this.state;
|
|
if (state.passThrough) {
|
|
state.winningSubstream.stream.writeMessage(this.method.streamRequest(reqt));
|
|
} else {
|
|
delayOrExecute(new BufferEntry(this, reqt) { // from class: io.grpc.internal.RetriableStream.1SendMessageEntry
|
|
final RetriableStream this$0;
|
|
final Object val$message;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$message = reqt;
|
|
}
|
|
|
|
/* JADX WARN: Multi-variable type inference failed */
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.writeMessage(this.this$0.method.streamRequest(this.val$message));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final void request(int i) {
|
|
State state = this.state;
|
|
if (state.passThrough) {
|
|
state.winningSubstream.stream.request(i);
|
|
} else {
|
|
delayOrExecute(new BufferEntry(this, i) { // from class: io.grpc.internal.RetriableStream.1RequestEntry
|
|
final RetriableStream this$0;
|
|
final int val$numMessages;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$numMessages = i;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.request(this.val$numMessages);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final void flush() {
|
|
State state = this.state;
|
|
if (state.passThrough) {
|
|
state.winningSubstream.stream.flush();
|
|
} else {
|
|
delayOrExecute(new BufferEntry(this) { // from class: io.grpc.internal.RetriableStream.1FlushEntry
|
|
final RetriableStream this$0;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.flush();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final boolean isReady() {
|
|
Iterator<Substream> it = this.state.drainedSubstreams.iterator();
|
|
while (it.hasNext()) {
|
|
if (it.next().stream.isReady()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public void optimizeForDirectExecutor() {
|
|
delayOrExecute(new BufferEntry(this) { // from class: io.grpc.internal.RetriableStream.1OptimizeDirectEntry
|
|
final RetriableStream this$0;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.optimizeForDirectExecutor();
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final void setCompressor(Compressor compressor) {
|
|
delayOrExecute(new BufferEntry(this, compressor) { // from class: io.grpc.internal.RetriableStream.1CompressorEntry
|
|
final RetriableStream this$0;
|
|
final Compressor val$compressor;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$compressor = compressor;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setCompressor(this.val$compressor);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setFullStreamDecompression(boolean z) {
|
|
delayOrExecute(new BufferEntry(this, z) { // from class: io.grpc.internal.RetriableStream.1FullStreamDecompressionEntry
|
|
final RetriableStream this$0;
|
|
final boolean val$fullStreamDecompression;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$fullStreamDecompression = z;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setFullStreamDecompression(this.val$fullStreamDecompression);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.Stream
|
|
public final void setMessageCompression(boolean z) {
|
|
delayOrExecute(new BufferEntry(this, z) { // from class: io.grpc.internal.RetriableStream.1MessageCompressionEntry
|
|
final RetriableStream this$0;
|
|
final boolean val$enable;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$enable = z;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setMessageCompression(this.val$enable);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void halfClose() {
|
|
delayOrExecute(new BufferEntry(this) { // from class: io.grpc.internal.RetriableStream.1HalfCloseEntry
|
|
final RetriableStream this$0;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.halfClose();
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setAuthority(String str) {
|
|
delayOrExecute(new BufferEntry(this, str) { // from class: io.grpc.internal.RetriableStream.1AuthorityEntry
|
|
final RetriableStream this$0;
|
|
final String val$authority;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$authority = str;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setAuthority(this.val$authority);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setDecompressorRegistry(DecompressorRegistry decompressorRegistry) {
|
|
delayOrExecute(new BufferEntry(this, decompressorRegistry) { // from class: io.grpc.internal.RetriableStream.1DecompressorRegistryEntry
|
|
final RetriableStream this$0;
|
|
final DecompressorRegistry val$decompressorRegistry;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$decompressorRegistry = decompressorRegistry;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setDecompressorRegistry(this.val$decompressorRegistry);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setMaxInboundMessageSize(int i) {
|
|
delayOrExecute(new BufferEntry(this, i) { // from class: io.grpc.internal.RetriableStream.1MaxInboundMessageSizeEntry
|
|
final RetriableStream this$0;
|
|
final int val$maxSize;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$maxSize = i;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setMaxInboundMessageSize(this.val$maxSize);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setMaxOutboundMessageSize(int i) {
|
|
delayOrExecute(new BufferEntry(this, i) { // from class: io.grpc.internal.RetriableStream.1MaxOutboundMessageSizeEntry
|
|
final RetriableStream this$0;
|
|
final int val$maxSize;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$maxSize = i;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setMaxOutboundMessageSize(this.val$maxSize);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final void setDeadline(Deadline deadline) {
|
|
delayOrExecute(new BufferEntry(this, deadline) { // from class: io.grpc.internal.RetriableStream.1DeadlineEntry
|
|
final RetriableStream this$0;
|
|
final Deadline val$deadline;
|
|
|
|
{
|
|
this.this$0 = this;
|
|
this.val$deadline = deadline;
|
|
}
|
|
|
|
@Override // io.grpc.internal.RetriableStream.BufferEntry
|
|
public void runWith(Substream substream) {
|
|
substream.stream.setDeadline(this.val$deadline);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public final Attributes getAttributes() {
|
|
if (this.state.winningSubstream != null) {
|
|
return this.state.winningSubstream.stream.getAttributes();
|
|
}
|
|
return Attributes.EMPTY;
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStream
|
|
public void appendTimeoutInsight(InsightBuilder insightBuilder) {
|
|
State state;
|
|
synchronized (this.lock) {
|
|
insightBuilder.appendKeyValue("closed", this.closedSubstreamsInsight);
|
|
state = this.state;
|
|
}
|
|
if (state.winningSubstream != null) {
|
|
InsightBuilder insightBuilder2 = new InsightBuilder();
|
|
state.winningSubstream.stream.appendTimeoutInsight(insightBuilder2);
|
|
insightBuilder.appendKeyValue("committed", insightBuilder2);
|
|
return;
|
|
}
|
|
InsightBuilder insightBuilder3 = new InsightBuilder();
|
|
for (Substream substream : state.drainedSubstreams) {
|
|
InsightBuilder insightBuilder4 = new InsightBuilder();
|
|
substream.stream.appendTimeoutInsight(insightBuilder4);
|
|
insightBuilder3.append(insightBuilder4);
|
|
}
|
|
insightBuilder.appendKeyValue("open", insightBuilder3);
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public boolean hasPotentialHedging(State state) {
|
|
return state.winningSubstream == null && state.hedgingAttemptCount < this.hedgingPolicy.maxAttempts && !state.hedgingFrozen;
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: private */
|
|
public void freezeHedging() {
|
|
Future<?> future;
|
|
synchronized (this.lock) {
|
|
FutureCanceller futureCanceller = this.scheduledHedging;
|
|
future = null;
|
|
if (futureCanceller != null) {
|
|
Future<?> markCancelled = futureCanceller.markCancelled();
|
|
this.scheduledHedging = null;
|
|
future = markCancelled;
|
|
}
|
|
this.state = this.state.freezeHedging();
|
|
}
|
|
if (future != null) {
|
|
future.cancel(false);
|
|
}
|
|
}
|
|
|
|
/* loaded from: classes6.dex */
|
|
final class Sublistener implements ClientStreamListener {
|
|
final Substream substream;
|
|
final RetriableStream this$0;
|
|
|
|
Sublistener(RetriableStream retriableStream, Substream substream) {
|
|
this.this$0 = retriableStream;
|
|
this.substream = substream;
|
|
}
|
|
|
|
@Override // io.grpc.internal.ClientStreamListener
|
|
public final void headersRead(Metadata metadata) {
|
|
this.this$0.commitAndRun(this.substream);
|
|
if (this.this$0.state.winningSubstream == this.substream) {
|
|
if (this.this$0.throttle != null) {
|
|
this.this$0.throttle.onSuccess();
|
|
}
|
|
this.this$0.listenerSerializeExecutor.execute(new Runnable(this, metadata) { // from class: io.grpc.internal.RetriableStream.Sublistener.1
|
|
final Sublistener this$1;
|
|
final Metadata val$headers;
|
|
|
|
{
|
|
this.this$1 = this;
|
|
this.val$headers = metadata;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
this.this$1.this$0.masterListener.headersRead(this.val$headers);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/* JADX WARN: Code restructure failed: missing block: B:28:0x00a8, code lost:
|
|
|
|
if (r5.this$0.state.activeHedges.size() == 1) goto L28;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:30:0x00ad, code lost:
|
|
|
|
if (r1 != false) goto L38;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:41:0x00c3, code lost:
|
|
|
|
if (r5.this$0.retryPolicy.maxAttempts != 1) goto L39;
|
|
*/
|
|
/* JADX WARN: Code restructure failed: missing block: B:60:0x013e, code lost:
|
|
|
|
if (r5.this$0.state.activeHedges.isEmpty() == false) goto L59;
|
|
*/
|
|
@Override // io.grpc.internal.ClientStreamListener
|
|
/*
|
|
Code decompiled incorrectly, please refer to instructions dump.
|
|
To view partially-correct add '--show-bad-code' argument
|
|
*/
|
|
public final void closed(io.grpc.Status r6, io.grpc.internal.ClientStreamListener.RpcProgress r7, io.grpc.Metadata r8) {
|
|
/*
|
|
Method dump skipped, instructions count: 420
|
|
To view this dump add '--comments-level debug' option
|
|
*/
|
|
throw new UnsupportedOperationException("Method not decompiled: io.grpc.internal.RetriableStream.Sublistener.closed(io.grpc.Status, io.grpc.internal.ClientStreamListener$RpcProgress, io.grpc.Metadata):void");
|
|
}
|
|
|
|
/* renamed from: io.grpc.internal.RetriableStream$Sublistener$1RetryBackoffRunnable, reason: invalid class name */
|
|
/* loaded from: classes6.dex */
|
|
class C1RetryBackoffRunnable implements Runnable {
|
|
final Sublistener this$1;
|
|
|
|
C1RetryBackoffRunnable(Sublistener sublistener) {
|
|
this.this$1 = sublistener;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
this.this$1.this$0.callExecutor.execute(new Runnable(this) { // from class: io.grpc.internal.RetriableStream.Sublistener.1RetryBackoffRunnable.1
|
|
final C1RetryBackoffRunnable this$2;
|
|
|
|
{
|
|
this.this$2 = this;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
this.this$2.this$1.this$0.drain(this.this$2.this$1.this$0.createSubstream(this.this$2.this$1.substream.previousAttemptCount + 1, false));
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
private RetryPlan makeRetryDecision(Status status, Metadata metadata) {
|
|
long nanos;
|
|
long j = 0;
|
|
boolean z = false;
|
|
if (this.this$0.retryPolicy != null) {
|
|
boolean contains = this.this$0.retryPolicy.retryableStatusCodes.contains(status.getCode());
|
|
Integer pushbackMills = getPushbackMills(metadata);
|
|
boolean z2 = (this.this$0.throttle == null || (!contains && (pushbackMills == null || pushbackMills.intValue() >= 0))) ? false : !this.this$0.throttle.onQualifiedFailureThenCheckIsAboveThreshold();
|
|
if (this.this$0.retryPolicy.maxAttempts > this.substream.previousAttemptCount + 1 && !z2) {
|
|
if (pushbackMills == null) {
|
|
if (contains) {
|
|
nanos = (long) (this.this$0.nextBackoffIntervalNanos * RetriableStream.random.nextDouble());
|
|
this.this$0.nextBackoffIntervalNanos = Math.min((long) (r0.nextBackoffIntervalNanos * this.this$0.retryPolicy.backoffMultiplier), this.this$0.retryPolicy.maxBackoffNanos);
|
|
j = nanos;
|
|
z = true;
|
|
}
|
|
} else if (pushbackMills.intValue() >= 0) {
|
|
nanos = TimeUnit.MILLISECONDS.toNanos(pushbackMills.intValue());
|
|
RetriableStream retriableStream = this.this$0;
|
|
retriableStream.nextBackoffIntervalNanos = retriableStream.retryPolicy.initialBackoffNanos;
|
|
j = nanos;
|
|
z = true;
|
|
}
|
|
}
|
|
return new RetryPlan(z, j);
|
|
}
|
|
return new RetryPlan(false, 0L);
|
|
}
|
|
|
|
private HedgingPlan makeHedgingDecision(Status status, Metadata metadata) {
|
|
Integer pushbackMills = getPushbackMills(metadata);
|
|
boolean z = !this.this$0.hedgingPolicy.nonFatalStatusCodes.contains(status.getCode());
|
|
return new HedgingPlan((z || ((this.this$0.throttle == null || (z && (pushbackMills == null || pushbackMills.intValue() >= 0))) ? false : this.this$0.throttle.onQualifiedFailureThenCheckIsAboveThreshold() ^ true)) ? false : true, pushbackMills);
|
|
}
|
|
|
|
private Integer getPushbackMills(Metadata metadata) {
|
|
String str = (String) metadata.get(RetriableStream.GRPC_RETRY_PUSHBACK_MS);
|
|
if (str == null) {
|
|
return null;
|
|
}
|
|
try {
|
|
return Integer.valueOf(str);
|
|
} catch (NumberFormatException unused) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
@Override // io.grpc.internal.StreamListener
|
|
public final void messagesAvailable(StreamListener.MessageProducer messageProducer) {
|
|
State state = this.this$0.state;
|
|
Preconditions.checkState(state.winningSubstream != null, "Headers should be received prior to messages.");
|
|
if (state.winningSubstream != this.substream) {
|
|
return;
|
|
}
|
|
this.this$0.listenerSerializeExecutor.execute(new Runnable(this, messageProducer) { // from class: io.grpc.internal.RetriableStream.Sublistener.5
|
|
final Sublistener this$1;
|
|
final StreamListener.MessageProducer val$producer;
|
|
|
|
{
|
|
this.this$1 = this;
|
|
this.val$producer = messageProducer;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
this.this$1.this$0.masterListener.messagesAvailable(this.val$producer);
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override // io.grpc.internal.StreamListener
|
|
public final void onReady() {
|
|
if (this.this$0.isReady()) {
|
|
this.this$0.listenerSerializeExecutor.execute(new Runnable(this) { // from class: io.grpc.internal.RetriableStream.Sublistener.6
|
|
final Sublistener this$1;
|
|
|
|
{
|
|
this.this$1 = this;
|
|
}
|
|
|
|
@Override // java.lang.Runnable
|
|
public void run() {
|
|
if (this.this$1.this$0.isClosed) {
|
|
return;
|
|
}
|
|
this.this$1.this$0.masterListener.onReady();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class State {
|
|
final Collection<Substream> activeHedges;
|
|
final List<BufferEntry> buffer;
|
|
final boolean cancelled;
|
|
final Collection<Substream> drainedSubstreams;
|
|
final int hedgingAttemptCount;
|
|
final boolean hedgingFrozen;
|
|
final boolean passThrough;
|
|
final Substream winningSubstream;
|
|
|
|
State(List<BufferEntry> list, Collection<Substream> collection, Collection<Substream> collection2, Substream substream, boolean z, boolean z2, boolean z3, int i) {
|
|
this.buffer = list;
|
|
this.drainedSubstreams = (Collection) Preconditions.checkNotNull(collection, "drainedSubstreams");
|
|
this.winningSubstream = substream;
|
|
this.activeHedges = collection2;
|
|
this.cancelled = z;
|
|
this.passThrough = z2;
|
|
this.hedgingFrozen = z3;
|
|
this.hedgingAttemptCount = i;
|
|
Preconditions.checkState(!z2 || list == null, "passThrough should imply buffer is null");
|
|
Preconditions.checkState((z2 && substream == null) ? false : true, "passThrough should imply winningSubstream != null");
|
|
Preconditions.checkState(!z2 || (collection.size() == 1 && collection.contains(substream)) || (collection.size() == 0 && substream.closed), "passThrough should imply winningSubstream is drained");
|
|
Preconditions.checkState((z && substream == null) ? false : true, "cancelled should imply committed");
|
|
}
|
|
|
|
final State cancelled() {
|
|
return new State(this.buffer, this.drainedSubstreams, this.activeHedges, this.winningSubstream, true, this.passThrough, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State substreamDrained(Substream substream) {
|
|
Collection unmodifiableCollection;
|
|
Preconditions.checkState(!this.passThrough, "Already passThrough");
|
|
if (substream.closed) {
|
|
unmodifiableCollection = this.drainedSubstreams;
|
|
} else if (this.drainedSubstreams.isEmpty()) {
|
|
unmodifiableCollection = Collections.singletonList(substream);
|
|
} else {
|
|
ArrayList arrayList = new ArrayList(this.drainedSubstreams);
|
|
arrayList.add(substream);
|
|
unmodifiableCollection = Collections.unmodifiableCollection(arrayList);
|
|
}
|
|
Collection collection = unmodifiableCollection;
|
|
Substream substream2 = this.winningSubstream;
|
|
boolean z = substream2 != null;
|
|
List<BufferEntry> list = this.buffer;
|
|
if (z) {
|
|
Preconditions.checkState(substream2 == substream, "Another RPC attempt has already committed");
|
|
list = null;
|
|
}
|
|
return new State(list, collection, this.activeHedges, this.winningSubstream, this.cancelled, z, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State substreamClosed(Substream substream) {
|
|
substream.closed = true;
|
|
if (!this.drainedSubstreams.contains(substream)) {
|
|
return this;
|
|
}
|
|
ArrayList arrayList = new ArrayList(this.drainedSubstreams);
|
|
arrayList.remove(substream);
|
|
return new State(this.buffer, Collections.unmodifiableCollection(arrayList), this.activeHedges, this.winningSubstream, this.cancelled, this.passThrough, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State committed(Substream substream) {
|
|
List<BufferEntry> list;
|
|
Collection emptyList;
|
|
boolean z;
|
|
Preconditions.checkState(this.winningSubstream == null, "Already committed");
|
|
List<BufferEntry> list2 = this.buffer;
|
|
if (this.drainedSubstreams.contains(substream)) {
|
|
emptyList = Collections.singleton(substream);
|
|
z = true;
|
|
list = null;
|
|
} else {
|
|
list = list2;
|
|
emptyList = Collections.emptyList();
|
|
z = false;
|
|
}
|
|
return new State(list, emptyList, this.activeHedges, substream, this.cancelled, z, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State freezeHedging() {
|
|
return this.hedgingFrozen ? this : new State(this.buffer, this.drainedSubstreams, this.activeHedges, this.winningSubstream, this.cancelled, this.passThrough, true, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State addActiveHedge(Substream substream) {
|
|
Collection unmodifiableCollection;
|
|
Preconditions.checkState(!this.hedgingFrozen, "hedging frozen");
|
|
Preconditions.checkState(this.winningSubstream == null, "already committed");
|
|
if (this.activeHedges == null) {
|
|
unmodifiableCollection = Collections.singleton(substream);
|
|
} else {
|
|
ArrayList arrayList = new ArrayList(this.activeHedges);
|
|
arrayList.add(substream);
|
|
unmodifiableCollection = Collections.unmodifiableCollection(arrayList);
|
|
}
|
|
return new State(this.buffer, this.drainedSubstreams, unmodifiableCollection, this.winningSubstream, this.cancelled, this.passThrough, this.hedgingFrozen, this.hedgingAttemptCount + 1);
|
|
}
|
|
|
|
final State removeActiveHedge(Substream substream) {
|
|
ArrayList arrayList = new ArrayList(this.activeHedges);
|
|
arrayList.remove(substream);
|
|
return new State(this.buffer, this.drainedSubstreams, Collections.unmodifiableCollection(arrayList), this.winningSubstream, this.cancelled, this.passThrough, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
|
|
final State replaceActiveHedge(Substream substream, Substream substream2) {
|
|
ArrayList arrayList = new ArrayList(this.activeHedges);
|
|
arrayList.remove(substream);
|
|
arrayList.add(substream2);
|
|
return new State(this.buffer, this.drainedSubstreams, Collections.unmodifiableCollection(arrayList), this.winningSubstream, this.cancelled, this.passThrough, this.hedgingFrozen, this.hedgingAttemptCount);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class Substream {
|
|
boolean bufferLimitExceeded;
|
|
boolean closed;
|
|
final int previousAttemptCount;
|
|
ClientStream stream;
|
|
|
|
Substream(int i) {
|
|
this.previousAttemptCount = i;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public class BufferSizeTracer extends ClientStreamTracer {
|
|
long bufferNeeded;
|
|
private final Substream substream;
|
|
final RetriableStream this$0;
|
|
|
|
BufferSizeTracer(RetriableStream retriableStream, Substream substream) {
|
|
this.this$0 = retriableStream;
|
|
this.substream = substream;
|
|
}
|
|
|
|
@Override // io.grpc.StreamTracer
|
|
public void outboundWireSize(long j) {
|
|
if (this.this$0.state.winningSubstream != null) {
|
|
return;
|
|
}
|
|
synchronized (this.this$0.lock) {
|
|
if (this.this$0.state.winningSubstream == null && !this.substream.closed) {
|
|
long j2 = this.bufferNeeded + j;
|
|
this.bufferNeeded = j2;
|
|
if (j2 <= this.this$0.perRpcBufferUsed) {
|
|
return;
|
|
}
|
|
if (this.bufferNeeded <= this.this$0.perRpcBufferLimit) {
|
|
long addAndGet = this.this$0.channelBufferUsed.addAndGet(this.bufferNeeded - this.this$0.perRpcBufferUsed);
|
|
this.this$0.perRpcBufferUsed = this.bufferNeeded;
|
|
if (addAndGet > this.this$0.channelBufferLimit) {
|
|
this.substream.bufferLimitExceeded = true;
|
|
}
|
|
} else {
|
|
this.substream.bufferLimitExceeded = true;
|
|
}
|
|
Runnable commit = this.substream.bufferLimitExceeded ? this.this$0.commit(this.substream) : null;
|
|
if (commit != null) {
|
|
commit.run();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class ChannelBufferMeter {
|
|
private final AtomicLong bufferUsed = new AtomicLong();
|
|
|
|
final long addAndGet(long j) {
|
|
return this.bufferUsed.addAndGet(j);
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class Throttle {
|
|
private static final int THREE_DECIMAL_PLACES_SCALE_UP = 1000;
|
|
final int maxTokens;
|
|
final int threshold;
|
|
final AtomicInteger tokenCount;
|
|
final int tokenRatio;
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
public Throttle(float f, float f2) {
|
|
AtomicInteger atomicInteger = new AtomicInteger();
|
|
this.tokenCount = atomicInteger;
|
|
this.tokenRatio = (int) (f2 * 1000.0f);
|
|
int i = (int) (f * 1000.0f);
|
|
this.maxTokens = i;
|
|
this.threshold = i / 2;
|
|
atomicInteger.set(i);
|
|
}
|
|
|
|
final boolean isAboveThreshold() {
|
|
return this.tokenCount.get() > this.threshold;
|
|
}
|
|
|
|
final boolean onQualifiedFailureThenCheckIsAboveThreshold() {
|
|
int i;
|
|
int i2;
|
|
do {
|
|
i = this.tokenCount.get();
|
|
if (i == 0) {
|
|
return false;
|
|
}
|
|
i2 = i + IpLibUtil.KIPP_IP_LICENSING_FAILURE;
|
|
} while (!this.tokenCount.compareAndSet(i, Math.max(i2, 0)));
|
|
return i2 > this.threshold;
|
|
}
|
|
|
|
final void onSuccess() {
|
|
int i;
|
|
int i2;
|
|
do {
|
|
i = this.tokenCount.get();
|
|
i2 = this.maxTokens;
|
|
if (i == i2) {
|
|
return;
|
|
}
|
|
} while (!this.tokenCount.compareAndSet(i, Math.min(this.tokenRatio + i, i2)));
|
|
}
|
|
|
|
public final boolean equals(Object obj) {
|
|
if (this == obj) {
|
|
return true;
|
|
}
|
|
if (!(obj instanceof Throttle)) {
|
|
return false;
|
|
}
|
|
Throttle throttle = (Throttle) obj;
|
|
return this.maxTokens == throttle.maxTokens && this.tokenRatio == throttle.tokenRatio;
|
|
}
|
|
|
|
public final int hashCode() {
|
|
return Objects.hashCode(Integer.valueOf(this.maxTokens), Integer.valueOf(this.tokenRatio));
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class RetryPlan {
|
|
final long backoffNanos;
|
|
final boolean shouldRetry;
|
|
|
|
RetryPlan(boolean z, long j) {
|
|
this.shouldRetry = z;
|
|
this.backoffNanos = j;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class HedgingPlan {
|
|
final Integer hedgingPushbackMillis;
|
|
final boolean isHedgeable;
|
|
|
|
public HedgingPlan(boolean z, Integer num) {
|
|
this.isHedgeable = z;
|
|
this.hedgingPushbackMillis = num;
|
|
}
|
|
}
|
|
|
|
/* JADX INFO: Access modifiers changed from: package-private */
|
|
/* loaded from: classes6.dex */
|
|
public static final class FutureCanceller {
|
|
boolean cancelled;
|
|
Future<?> future;
|
|
final Object lock;
|
|
|
|
FutureCanceller(Object obj) {
|
|
this.lock = obj;
|
|
}
|
|
|
|
final void setFuture(Future<?> future) {
|
|
synchronized (this.lock) {
|
|
if (!this.cancelled) {
|
|
this.future = future;
|
|
}
|
|
}
|
|
}
|
|
|
|
final Future<?> markCancelled() {
|
|
this.cancelled = true;
|
|
return this.future;
|
|
}
|
|
|
|
final boolean isCancelled() {
|
|
return this.cancelled;
|
|
}
|
|
}
|
|
|
|
static void setRandom(Random random2) {
|
|
random = random2;
|
|
}
|
|
}
|