@@ -83,7 +83,6 @@ class CompletedAttemptMetric:
8383
8484 duration_ns : int
8585 end_status : StatusCode
86- first_response_latency_ns : int | None = None
8786 gfe_latency_ns : int | None = None
8887 application_blocking_time_ns : int = 0
8988 backoff_before_attempt_ns : int = 0
@@ -108,6 +107,7 @@ class CompletedOperationMetric:
108107 cluster_id : str
109108 zone : str
110109 is_streaming : bool
110+ first_response_latency_ns : int | None = None
111111 flow_throttling_time_ns : int = 0
112112
113113
@@ -120,9 +120,6 @@ class ActiveAttemptMetric:
120120
121121 # keep monotonic timestamps for active attempts
122122 start_time_ns : int = field (default_factory = time .monotonic_ns )
123- # the time it takes to recieve the first response from the server, in nanoseconds
124- # currently only tracked for ReadRows
125- first_response_latency_ns : int | None = None
126123 # the time taken by the backend, in nanoseconds. Taken from response header
127124 gfe_latency_ns : int | None = None
128125 # time waiting on user to process the response, in nanoseconds
@@ -159,6 +156,10 @@ class ActiveOperationMetric:
159156 is_streaming : bool = False # only True for read_rows operations
160157 was_completed : bool = False
161158 handlers : list [MetricsHandler ] = field (default_factory = list )
159+ # the time it takes to recieve the first response from the server, in nanoseconds
160+ # attached by interceptor
161+ # currently only tracked for ReadRows
162+ first_response_latency_ns : int | None = None
162163 # time waiting on flow control, in nanoseconds
163164 flow_throttling_time_ns : int = 0
164165
@@ -274,23 +275,6 @@ def _parse_response_metadata_blob(blob: bytes) -> Tuple[str, str] | None:
274275 # failed to parse metadata
275276 return None
276277
277- def attempt_first_response (self ) -> None :
278- """
279- Called to mark the timestamp of the first completed response for the
280- active attempt.
281-
282- Assumes operation is in ACTIVE_ATTEMPT state.
283- """
284- if self .state != OperationState .ACTIVE_ATTEMPT or self .active_attempt is None :
285- return self ._handle_error (
286- INVALID_STATE_ERROR .format ("attempt_first_response" , self .state )
287- )
288- if self .active_attempt .first_response_latency_ns is not None :
289- return self ._handle_error ("Attempt already received first response" )
290- self .active_attempt .first_response_latency_ns = (
291- time .monotonic_ns () - self .active_attempt .start_time_ns
292- )
293-
294278 def end_attempt_with_status (self , status : StatusCode | Exception ) -> None :
295279 """
296280 Called to mark the end of an attempt for the operation.
@@ -311,7 +295,6 @@ def end_attempt_with_status(self, status: StatusCode | Exception) -> None:
311295 if isinstance (status , Exception ):
312296 status = self ._exc_to_status (status )
313297 complete_attempt = CompletedAttemptMetric (
314- first_response_latency_ns = self .active_attempt .first_response_latency_ns ,
315298 duration_ns = time .monotonic_ns () - self .active_attempt .start_time_ns ,
316299 end_status = status ,
317300 gfe_latency_ns = self .active_attempt .gfe_latency_ns ,
@@ -355,6 +338,7 @@ def end_with_status(self, status: StatusCode | Exception) -> None:
355338 cluster_id = self .cluster_id or DEFAULT_CLUSTER_ID ,
356339 zone = self .zone or DEFAULT_ZONE ,
357340 is_streaming = self .is_streaming ,
341+ first_response_latency_ns = self .first_response_latency_ns ,
358342 flow_throttling_time_ns = self .flow_throttling_time_ns ,
359343 )
360344 for handler in self .handlers :
0 commit comments