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();