mirror of https://github.com/grpc/grpc-java.git
core: remember last pick status in no real stream (#11851)
This commit is contained in:
parent
122b683717
commit
7585b1607d
|
|
@ -129,8 +129,9 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
if (state.shutdownStatus != null) {
|
if (state.shutdownStatus != null) {
|
||||||
return new FailingClientStream(state.shutdownStatus, tracers);
|
return new FailingClientStream(state.shutdownStatus, tracers);
|
||||||
}
|
}
|
||||||
|
PickResult pickResult = null;
|
||||||
if (state.lastPicker != null) {
|
if (state.lastPicker != null) {
|
||||||
PickResult pickResult = state.lastPicker.pickSubchannel(args);
|
pickResult = state.lastPicker.pickSubchannel(args);
|
||||||
callOptions = args.getCallOptions();
|
callOptions = args.getCallOptions();
|
||||||
// User code provided authority takes precedence over the LB provided one.
|
// User code provided authority takes precedence over the LB provided one.
|
||||||
if (callOptions.getAuthority() == null
|
if (callOptions.getAuthority() == null
|
||||||
|
|
@ -156,7 +157,7 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
PickerState newerState = pickerState;
|
PickerState newerState = pickerState;
|
||||||
if (state == newerState) {
|
if (state == newerState) {
|
||||||
return createPendingStream(args, tracers);
|
return createPendingStream(args, tracers, pickResult);
|
||||||
}
|
}
|
||||||
state = newerState;
|
state = newerState;
|
||||||
}
|
}
|
||||||
|
|
@ -171,9 +172,12 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
* schedule tasks on syncContext.
|
* schedule tasks on syncContext.
|
||||||
*/
|
*/
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private PendingStream createPendingStream(
|
private PendingStream createPendingStream(PickSubchannelArgs args, ClientStreamTracer[] tracers,
|
||||||
PickSubchannelArgs args, ClientStreamTracer[] tracers) {
|
PickResult pickResult) {
|
||||||
PendingStream pendingStream = new PendingStream(args, tracers);
|
PendingStream pendingStream = new PendingStream(args, tracers);
|
||||||
|
if (args.getCallOptions().isWaitForReady() && pickResult != null && pickResult.hasResult()) {
|
||||||
|
pendingStream.lastPickStatus = pickResult.getStatus();
|
||||||
|
}
|
||||||
pendingStreams.add(pendingStream);
|
pendingStreams.add(pendingStream);
|
||||||
if (getPendingStreamsCount() == 1) {
|
if (getPendingStreamsCount() == 1) {
|
||||||
syncContext.executeLater(reportTransportInUse);
|
syncContext.executeLater(reportTransportInUse);
|
||||||
|
|
@ -293,6 +297,9 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
for (final PendingStream stream : toProcess) {
|
for (final PendingStream stream : toProcess) {
|
||||||
PickResult pickResult = picker.pickSubchannel(stream.args);
|
PickResult pickResult = picker.pickSubchannel(stream.args);
|
||||||
CallOptions callOptions = stream.args.getCallOptions();
|
CallOptions callOptions = stream.args.getCallOptions();
|
||||||
|
if (callOptions.isWaitForReady() && pickResult.hasResult()) {
|
||||||
|
stream.lastPickStatus = pickResult.getStatus();
|
||||||
|
}
|
||||||
final ClientTransport transport = GrpcUtil.getTransportFromPickResult(pickResult,
|
final ClientTransport transport = GrpcUtil.getTransportFromPickResult(pickResult,
|
||||||
callOptions.isWaitForReady());
|
callOptions.isWaitForReady());
|
||||||
if (transport != null) {
|
if (transport != null) {
|
||||||
|
|
@ -349,6 +356,7 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
private final PickSubchannelArgs args;
|
private final PickSubchannelArgs args;
|
||||||
private final Context context = Context.current();
|
private final Context context = Context.current();
|
||||||
private final ClientStreamTracer[] tracers;
|
private final ClientStreamTracer[] tracers;
|
||||||
|
private volatile Status lastPickStatus;
|
||||||
|
|
||||||
private PendingStream(PickSubchannelArgs args, ClientStreamTracer[] tracers) {
|
private PendingStream(PickSubchannelArgs args, ClientStreamTracer[] tracers) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
|
@ -405,6 +413,10 @@ final class DelayedClientTransport implements ManagedClientTransport {
|
||||||
public void appendTimeoutInsight(InsightBuilder insight) {
|
public void appendTimeoutInsight(InsightBuilder insight) {
|
||||||
if (args.getCallOptions().isWaitForReady()) {
|
if (args.getCallOptions().isWaitForReady()) {
|
||||||
insight.append("wait_for_ready");
|
insight.append("wait_for_ready");
|
||||||
|
Status status = lastPickStatus;
|
||||||
|
if (status != null && !status.isOk()) {
|
||||||
|
insight.appendKeyValue("Last Pick Failure", status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.appendTimeoutInsight(insight);
|
super.appendTimeoutInsight(insight);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -745,6 +745,23 @@ public class DelayedClientTransportTest {
|
||||||
.matches("\\[wait_for_ready, buffered_nanos=[0-9]+\\, waiting_for_connection]");
|
.matches("\\[wait_for_ready, buffered_nanos=[0-9]+\\, waiting_for_connection]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pendingStream_appendTimeoutInsight_waitForReady_withLastPickFailure() {
|
||||||
|
ClientStream stream = delayedTransport.newStream(
|
||||||
|
method, headers, callOptions.withWaitForReady(), tracers);
|
||||||
|
stream.start(streamListener);
|
||||||
|
SubchannelPicker picker = mock(SubchannelPicker.class);
|
||||||
|
when(picker.pickSubchannel(any(PickSubchannelArgs.class)))
|
||||||
|
.thenReturn(PickResult.withError(Status.PERMISSION_DENIED));
|
||||||
|
delayedTransport.reprocess(picker);
|
||||||
|
InsightBuilder insight = new InsightBuilder();
|
||||||
|
stream.appendTimeoutInsight(insight);
|
||||||
|
assertThat(insight.toString())
|
||||||
|
.matches("\\[wait_for_ready, "
|
||||||
|
+ "Last Pick Failure=Status\\{code=PERMISSION_DENIED, description=null, cause=null\\},"
|
||||||
|
+ " buffered_nanos=[0-9]+, waiting_for_connection]");
|
||||||
|
}
|
||||||
|
|
||||||
private static TransportProvider newTransportProvider(final ClientTransport transport) {
|
private static TransportProvider newTransportProvider(final ClientTransport transport) {
|
||||||
return new TransportProvider() {
|
return new TransportProvider() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue