@@ -58,42 +58,45 @@ public void createPendingStream() {
5858 }
5959
6060 /**
61- * Called when an attempt-level delay segment (such as waiting for a load balancing pick or
62- * connection establishment) starts.
61+ * Called when an attempt-level delay (such as waiting for a load balancing pick or connection
62+ * establishment) starts, or when the {@code delayType} of the ongoing delay changes, in which
63+ * case {@link #recordDelayEnd} is called for the previous delay first.
6364 *
64- * <p>This method is invoked synchronously on the attempt thread. Implementations should start
65- * internal timers or child tracing spans (named strictly {@code "Attempt Delay"}) carrying the
66- * canonical {@code grpc.delay_type} attribute.
65+ * <p>Implementations should start a timer and open a child tracing span (named strictly
66+ * {@code "Delay"}) carrying the canonical {@code grpc.delay_type} attribute.
6767 *
6868 * @param delayType canonical low-cardinality label categorizing the delay (e.g., "connecting")
6969 * @param delayReason high-cardinality diagnostic string describing granular runtime conditions
70- * @since 1.82 .0
70+ * @since 1.86 .0
7171 */
72- public void recordAttemptDelayStart (String delayType , String delayReason ) {
72+ public void recordDelayStart (String delayType , String delayReason ) {
7373 }
7474
7575 /**
76- * Called when an attempt-level delay reason changes while the overall delay type remains
77- * constant (for example, when a priority load balancing policy fails over between tiers ).
76+ * Called when an attempt-level delay reason changes while the delay type remains constant (for
77+ * example, when a load balancing policy updates its connection status detail ).
7878 *
79- * <p>Implementations should record structured events (such as {@code "Delay state transition "})
80- * on the active delay span without recreating the span or resetting cumulative timers.
79+ * <p>Implementations should record a structured event (such as {@code "Delay triggered "}) on
80+ * the active delay span without recreating the span or resetting cumulative timers.
8181 *
82+ * @param delayType canonical low-cardinality label of the ongoing delay
8283 * @param delayReason updated high-cardinality diagnostic string describing new conditions
83- * @since 1.82 .0
84+ * @since 1.86 .0
8485 */
85- public void recordAttemptDelayReasonChanged ( String delayReason ) {
86+ public void recordDelayReasonChanged ( String delayType , String delayReason ) {
8687 }
8788
8889 /**
89- * Called when an attempt-level delay segment ends upon successful pick or stream creation.
90+ * Called when an attempt-level delay ends upon successful pick or stream creation, or when the
91+ * attempt is cancelled or reaches its deadline while still waiting.
9092 *
91- * <p>Implementations should simultaneously close active child tracing spans and record elapsed
92- * duration to the {@code grpc.client.attempt.delay.duration} histogram.
93+ * <p>Implementations should close the active child tracing span and record the elapsed duration
94+ * to the {@code grpc.client.attempt.delay.duration} histogram labeled with {@code delayType} .
9395 *
94- * @since 1.82.0
96+ * @param delayType canonical low-cardinality label of the delay being ended
97+ * @since 1.86.0
9598 */
96- public void recordAttemptDelayEnd ( ) {
99+ public void recordDelayEnd ( String delayType ) {
97100 }
98101
99102 /**
@@ -156,6 +159,47 @@ public abstract static class Factory {
156159 public ClientStreamTracer newClientStreamTracer (StreamInfo info , Metadata headers ) {
157160 throw new UnsupportedOperationException ("Not implemented" );
158161 }
162+
163+ /**
164+ * Called when a call-level delay (such as waiting for name resolution) starts before any
165+ * individual RPC attempt is created, or when the {@code delayType} of the ongoing delay
166+ * changes, in which case {@link #recordDelayEnd} is called for the previous delay first.
167+ *
168+ * <p>Implementations should start a timer and open a child tracing span (named strictly
169+ * {@code "Delay"}) carrying the canonical {@code grpc.delay_type} attribute.
170+ *
171+ * @param delayType canonical low-cardinality label categorizing the delay (e.g., "resolving")
172+ * @param delayReason high-cardinality diagnostic string describing granular runtime conditions
173+ * @since 1.86.0
174+ */
175+ public void recordDelayStart (String delayType , String delayReason ) {
176+ }
177+
178+ /**
179+ * Called when a call-level delay reason changes while the delay type remains constant.
180+ *
181+ * <p>Implementations should record a structured event (such as {@code "Delay triggered"}) on
182+ * the active call delay span without recreating the span or resetting timers.
183+ *
184+ * @param delayType canonical low-cardinality label of the ongoing delay
185+ * @param delayReason updated high-cardinality diagnostic string describing new conditions
186+ * @since 1.86.0
187+ */
188+ public void recordDelayReasonChanged (String delayType , String delayReason ) {
189+ }
190+
191+ /**
192+ * Called when a call-level delay ends upon successful name resolution, or when the RPC is
193+ * cancelled or reaches its deadline before resolution completes.
194+ *
195+ * <p>Implementations should close the active call delay span and record the elapsed duration
196+ * to the {@code grpc.client.call.delay.duration} histogram labeled with {@code delayType}.
197+ *
198+ * @param delayType canonical low-cardinality label of the delay being ended
199+ * @since 1.86.0
200+ */
201+ public void recordDelayEnd (String delayType ) {
202+ }
159203 }
160204
161205 /**
0 commit comments