Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit 2ef2c3c

Browse files
committed
convert all time variables to explicitly use ms
1 parent 3ffc7c0 commit 2ef2c3c

2 files changed

Lines changed: 87 additions & 84 deletions

File tree

google/cloud/bigtable/data/_metrics/data_model.py

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,13 @@ class CompletedAttemptMetric:
9494
"""
9595

9696
start_time: datetime.datetime
97-
duration: float
97+
duration_ms: float
9898
end_status: StatusCode
99-
first_response_latency: float | None = None
100-
gfe_latency: float | None = None
101-
application_blocking_time: float = 0.0
102-
backoff_before_attempt: float = 0.0
103-
grpc_throttling_time: float = 0.0
99+
first_response_latency_ms: float | None = None
100+
gfe_latency_ms: float | None = None
101+
application_blocking_time_ms: float = 0.0
102+
backoff_before_attempt_ms: float = 0.0
103+
grpc_throttling_time_ms: float = 0.0
104104

105105

106106
@dataclass(frozen=True)
@@ -112,13 +112,13 @@ class CompletedOperationMetric:
112112

113113
op_type: OperationType
114114
start_time: datetime.datetime
115-
duration: float
115+
duration_ms: float
116116
completed_attempts: list[CompletedAttemptMetric]
117117
final_status: StatusCode
118118
cluster_id: str
119119
zone: str
120120
is_streaming: bool
121-
flow_throttling_time: float = 0.0
121+
flow_throttling_time_ms: float = 0.0
122122

123123

124124
@dataclass
@@ -130,19 +130,19 @@ class ActiveAttemptMetric:
130130

131131
# keep both clock time and monotonic timestamps for active attempts
132132
start_time: TimeTuple = field(default_factory=TimeTuple)
133-
# the time it takes to recieve the first response from the server
133+
# the time it takes to recieve the first response from the server, in milliseconds
134134
# currently only tracked for ReadRows
135-
first_response_latency: float | None = None
136-
# the time taken by the backend. Taken from response header
137-
gfe_latency: float | None = None
138-
# time waiting on user to process the response
135+
first_response_latency_ms: float | None = None
136+
# the time taken by the backend, in milliseconds. Taken from response header
137+
gfe_latency_ms: float | None = None
138+
# time waiting on user to process the response, in milliseconds
139139
# currently only relevant for ReadRows
140-
application_blocking_time: float = 0.0
141-
# backoff time is added to application_blocking_time
142-
backoff_before_attempt: float = 0.0
143-
# time waiting on grpc channel
140+
application_blocking_time_ms: float = 0.0
141+
# backoff time is added to application_blocking_time_ms
142+
backoff_before_attempt_ms: float = 0.0
143+
# time waiting on grpc channel, in milliseconds
144144
# TODO: capture grpc_throttling_time
145-
grpc_throttling_time: float = 0.0
145+
grpc_throttling_time_ms: float = 0.0
146146

147147

148148
@dataclass
@@ -163,8 +163,8 @@ class ActiveOperationMetric:
163163
is_streaming: bool = False # only True for read_rows operations
164164
was_completed: bool = False
165165
handlers: list[MetricsHandler] = field(default_factory=list)
166-
# time waiting on flow control
167-
flow_throttling_time: float = 0.0
166+
# time waiting on flow control, in milliseconds
167+
flow_throttling_time_ms: float = 0.0
168168

169169
@property
170170
def state(self) -> OperationState:
@@ -208,11 +208,12 @@ def start_attempt(self) -> None:
208208
# find backoff value
209209
if self.backoff_generator and len(self.completed_attempts) > 0:
210210
# find the attempt's backoff by sending attempt number to generator
211-
backoff = self.backoff_generator.send(len(self.completed_attempts) - 1)
211+
# generator will return the backoff time in seconds, so convert to ms
212+
backoff_ms = self.backoff_generator.send(len(self.completed_attempts) - 1) * 1000
212213
else:
213-
backoff = 0
214+
backoff_ms = 0
214215

215-
self.active_attempt = ActiveAttemptMetric(backoff_before_attempt=backoff)
216+
self.active_attempt = ActiveAttemptMetric(backoff_before_attempt_ms=backoff_ms)
216217

217218
def add_response_metadata(self, metadata: dict[str, bytes | str]) -> None:
218219
"""
@@ -250,8 +251,7 @@ def add_response_metadata(self, metadata: dict[str, bytes | str]) -> None:
250251
if timing_header:
251252
timing_data = SERVER_TIMING_REGEX.match(timing_header)
252253
if timing_data and self.active_attempt:
253-
# convert from milliseconds to seconds
254-
self.active_attempt.gfe_latency = float(timing_data.group(1)) / 1000
254+
self.active_attempt.gfe_latency_ms = float(timing_data.group(1))
255255

256256
@staticmethod
257257
@lru_cache(maxsize=32)
@@ -286,11 +286,12 @@ def attempt_first_response(self) -> None:
286286
return self._handle_error(
287287
INVALID_STATE_ERROR.format("attempt_first_response", self.state)
288288
)
289-
if self.active_attempt.first_response_latency is not None:
289+
if self.active_attempt.first_response_latency_ms is not None:
290290
return self._handle_error("Attempt already received first response")
291-
self.active_attempt.first_response_latency = (
291+
# convert duration to milliseconds
292+
self.active_attempt.first_response_latency_ms = (
292293
time.monotonic() - self.active_attempt.start_time.monotonic
293-
)
294+
) * 1000
294295

295296
def end_attempt_with_status(self, status: StatusCode | Exception) -> None:
296297
"""
@@ -309,15 +310,15 @@ def end_attempt_with_status(self, status: StatusCode | Exception) -> None:
309310

310311
new_attempt = CompletedAttemptMetric(
311312
start_time=self.active_attempt.start_time.utc,
312-
first_response_latency=self.active_attempt.first_response_latency,
313-
duration=time.monotonic() - self.active_attempt.start_time.monotonic,
313+
first_response_latency_ms=self.active_attempt.first_response_latency_ms,
314+
duration_ms=(time.monotonic() - self.active_attempt.start_time.monotonic) * 1000,
314315
end_status=self._exc_to_status(status)
315316
if isinstance(status, Exception)
316317
else status,
317-
gfe_latency=self.active_attempt.gfe_latency,
318-
application_blocking_time=self.active_attempt.application_blocking_time,
319-
backoff_before_attempt=self.active_attempt.backoff_before_attempt,
320-
grpc_throttling_time=self.active_attempt.grpc_throttling_time,
318+
gfe_latency_ms=self.active_attempt.gfe_latency_ms,
319+
application_blocking_time_ms=self.active_attempt.application_blocking_time_ms,
320+
backoff_before_attempt_ms=self.active_attempt.backoff_before_attempt_ms,
321+
grpc_throttling_time_ms=self.active_attempt.grpc_throttling_time_ms,
321322
)
322323
self.completed_attempts.append(new_attempt)
323324
self.active_attempt = None
@@ -351,12 +352,12 @@ def end_with_status(self, status: StatusCode | Exception) -> None:
351352
op_type=self.op_type,
352353
start_time=self.start_time.utc,
353354
completed_attempts=self.completed_attempts,
354-
duration=time.monotonic() - self.start_time.monotonic,
355+
duration_ms=(time.monotonic() - self.start_time.monotonic) * 1000,
355356
final_status=final_status,
356357
cluster_id=self.cluster_id or DEFAULT_CLUSTER_ID,
357358
zone=self.zone or DEFAULT_ZONE,
358359
is_streaming=self.is_streaming,
359-
flow_throttling_time=self.flow_throttling_time,
360+
flow_throttling_time_ms=self.flow_throttling_time_ms,
360361
)
361362
for handler in self.handlers:
362363
handler.on_operation_complete(finalized)

0 commit comments

Comments
 (0)