diff --git a/api/src/main/java/io/grpc/ClientStreamTracer.java b/api/src/main/java/io/grpc/ClientStreamTracer.java index 53909f23740..8b3520a8dcd 100644 --- a/api/src/main/java/io/grpc/ClientStreamTracer.java +++ b/api/src/main/java/io/grpc/ClientStreamTracer.java @@ -39,6 +39,18 @@ public abstract class ClientStreamTracer extends StreamTracer { public void streamCreated(@Grpc.TransportAttr Attributes transportAttrs, Metadata headers) { } + /** + * Name resolution is completed and the connection starts getting established. This method is only + * invoked on the streams that encounter such delay. + * + *

gRPC buffers the client call if the remote address and configurations, e.g. timeouts and + * retry policy, are not ready. Asynchronously gRPC internally does the name resolution to get + * this information. The streams that are processed immediately on ready transports by the time + * the RPC comes do not go through the pending process, thus this callback will not be invoked. + */ + public void createPendingStream() { + } + /** * Headers has been sent to the socket. */ diff --git a/census/src/main/java/io/grpc/census/CensusTracingModule.java b/census/src/main/java/io/grpc/census/CensusTracingModule.java index 4fa9e28747b..dfe437780ba 100644 --- a/census/src/main/java/io/grpc/census/CensusTracingModule.java +++ b/census/src/main/java/io/grpc/census/CensusTracingModule.java @@ -299,6 +299,7 @@ private final class ClientTracer extends ClientStreamTracer { final Metadata.Key tracingHeader; final boolean isSampledToLocalTracing; volatile int seqNo; + boolean isPendingStream; ClientTracer( Span span, Span parentSpan, Metadata.Key tracingHeader, @@ -315,6 +316,14 @@ public void streamCreated(Attributes transportAtts, Metadata headers) { headers.discardAll(tracingHeader); headers.put(tracingHeader, span.getContext()); } + if (isPendingStream) { + span.addAnnotation("Delayed LB pick complete"); + } + } + + @Override + public void createPendingStream() { + isPendingStream = true; } @Override diff --git a/census/src/test/java/io/grpc/census/CensusModulesTest.java b/census/src/test/java/io/grpc/census/CensusModulesTest.java index 692395b362b..2447b2c01ff 100644 --- a/census/src/test/java/io/grpc/census/CensusModulesTest.java +++ b/census/src/test/java/io/grpc/census/CensusModulesTest.java @@ -746,6 +746,7 @@ public void clientBasicTracingDefaultSpan() { censusTracing.newClientCallTracer(spyClientSpan, method); Metadata headers = new Metadata(); ClientStreamTracer clientStreamTracer = callTracer.newClientStreamTracer(STREAM_INFO, headers); + clientStreamTracer.createPendingStream(); clientStreamTracer.streamCreated(Attributes.EMPTY, headers); verify(tracer).spanBuilderWithExplicitParent( eq("Attempt.package1.service2.method3"), eq(spyClientSpan)); @@ -767,6 +768,7 @@ public void clientBasicTracingDefaultSpan() { .putAttribute("previous-rpc-attempts", AttributeValue.longAttributeValue(0)); inOrder.verify(spyAttemptSpan) .putAttribute("transparent-retry", AttributeValue.booleanAttributeValue(false)); + inOrder.verify(spyAttemptSpan).addAnnotation("Delayed LB pick complete"); inOrder.verify(spyAttemptSpan, times(2)).addMessageEvent(messageEventCaptor.capture()); List events = messageEventCaptor.getAllValues(); assertEquals( diff --git a/core/src/main/java/io/grpc/internal/DelayedClientTransport.java b/core/src/main/java/io/grpc/internal/DelayedClientTransport.java index 2b1145d1c4b..d71de1f5d53 100644 --- a/core/src/main/java/io/grpc/internal/DelayedClientTransport.java +++ b/core/src/main/java/io/grpc/internal/DelayedClientTransport.java @@ -183,6 +183,9 @@ private PendingStream createPendingStream( if (getPendingStreamsCount() == 1) { syncContext.executeLater(reportTransportInUse); } + for (ClientStreamTracer streamTracer : tracers) { + streamTracer.createPendingStream(); + } return pendingStream; } diff --git a/core/src/main/java/io/grpc/internal/ForwardingClientStreamTracer.java b/core/src/main/java/io/grpc/internal/ForwardingClientStreamTracer.java index fd03564d396..4740a811f3a 100644 --- a/core/src/main/java/io/grpc/internal/ForwardingClientStreamTracer.java +++ b/core/src/main/java/io/grpc/internal/ForwardingClientStreamTracer.java @@ -34,6 +34,11 @@ public void streamCreated(Attributes transportAttrs, Metadata headers) { delegate().streamCreated(transportAttrs, headers); } + @Override + public void createPendingStream() { + delegate().createPendingStream(); + } + @Override public void outboundHeaders() { delegate().outboundHeaders(); diff --git a/core/src/main/java/io/grpc/util/ForwardingClientStreamTracer.java b/core/src/main/java/io/grpc/util/ForwardingClientStreamTracer.java index 7bb9d8cf71a..7317917887a 100644 --- a/core/src/main/java/io/grpc/util/ForwardingClientStreamTracer.java +++ b/core/src/main/java/io/grpc/util/ForwardingClientStreamTracer.java @@ -33,6 +33,11 @@ public void streamCreated(Attributes transportAttrs, Metadata headers) { delegate().streamCreated(transportAttrs, headers); } + @Override + public void createPendingStream() { + delegate().createPendingStream(); + } + @Override public void outboundHeaders() { delegate().outboundHeaders();