@@ -143,8 +143,11 @@ class ActiveOperationMetric:
143143 """
144144
145145 op_type : OperationType
146- uuid : str = str (uuid .uuid4 ())
147- backoff_generator : TrackedBackoffGenerator | None = None
146+ uuid : str = field (default_factory = lambda : str (uuid .uuid4 ()))
147+ # create a default backoff generator, initialized with standard default backoff values
148+ backoff_generator : TrackedBackoffGenerator = field (
149+ default_factory = lambda : TrackedBackoffGenerator (initial = 0.01 , maximum = 60 , multiplier = 2 )
150+ )
148151 # keep monotonic timestamps for active operations
149152 start_time_ns : int = field (default_factory = time .monotonic_ns )
150153 active_attempt : ActiveAttemptMetric | None = None
@@ -198,15 +201,16 @@ def start_attempt(self) -> ActiveAttemptMetric:
198201 INVALID_STATE_ERROR .format ("start_attempt" , self .state )
199202 )
200203
201- # find backoff value
202- if self .backoff_generator and len (self .completed_attempts ) > 0 :
203- # find the attempt's backoff by sending attempt number to generator
204- # generator will return the backoff time in seconds, so convert to nanoseconds
204+ try :
205+ # find backoff value before this attempt
206+ prev_attempt_idx = len (self .completed_attempts ) - 1
205207 backoff = self .backoff_generator .get_attempt_backoff (
206- len ( self . completed_attempts ) - 1
208+ prev_attempt_idx
207209 )
210+ # generator will return the backoff time in seconds, so convert to nanoseconds
208211 backoff_ns = int (backoff * 1e9 )
209- else :
212+ except IndexError :
213+ # backoff value not found
210214 backoff_ns = 0
211215
212216 self .active_attempt = ActiveAttemptMetric (backoff_before_attempt_ns = backoff_ns )
@@ -409,19 +413,19 @@ def _handle_error(message: str) -> None:
409413 full_message = f"Error in Bigtable Metrics: { message } "
410414 LOGGER .warning (full_message )
411415
412- async def __aenter__ (self ):
416+ def __aenter__ (self ):
413417 """
414- Implements the async context manager protocol for wrapping unary calls
418+ Implements the async manager protocol
415419
416420 Using the operation's context manager provides assurances that the operation
417421 is always closed when complete, with the proper status code automaticallty
418422 detected when an exception is raised.
419423 """
420424 return self
421425
422- async def __aexit__ (self , exc_type , exc_val , exc_tb ):
426+ def __aexit__ (self , exc_type , exc_val , exc_tb ):
423427 """
424- Implements the async context manager protocol for wrapping unary calls
428+ Implements the context manager protocol
425429
426430 The operation is automatically ended on exit, with the status determined
427431 by the exception type and value.
0 commit comments