[docs]defnow()->int:"""Gets current time in milliseconds since epoch"""returnint(time.time()*1000)
defnow_seconds()->float:returntime.time()
[docs]defuuid1()->str:"""Generates a string representation of a UUID1"""returnstr(uuid.uuid1())
[docs]defmillis(s:float)->float:"""Converts from seconds to milliseconds"""returns*1000
[docs]defseconds(ms:float)->float:"""Converts from milliseconds to seconds"""returnms/1000
[docs]defexponential_backoff(attempts:int,base_delay:float,max_delay:float|None=None,jitter:bool=True,)->float:""" Get the next delay for retries in exponential backoff. Args: attempts: Number of attempts so far base_delay: Base delay, in seconds max_delay: Max delay, in seconds. If None (default), there is no max. jitter: If True, add a random jitter to the delay Returns: Delay in seconds """ifmax_delayisNone:max_delay=float("inf")backoff=min(max_delay,base_delay*2**max(attempts-1,0))ifjitter:backoff=backoff*random()returnbackoff
[docs]asyncdefcancel_tasks(tasks:Iterable[asyncio.Task])->None:"""Cancel tasks and wait for all of them to finish"""fortaskintasks:task.cancel()awaitasyncio.gather(*tasks,return_exceptions=True)