asyncutils.altlocks¶
Non-conventional asynchronous synchronization primitives that may not adhere to the traditional lock interface.
Classes¶
Limit the rate of a function being called. |
|
Essentially invert the roles of the async enter and exit methods of a lock. |
|
A sync- and async-compatible context manager, inspired by |
|
An async barrier, that unlike traditional barriers, accumulates state from parties in a deque and makes it available once the barrier is tripped. |
|
A subclass of |
Module Contents¶
- class asyncutils.altlocks.CircuitBreaker[source]¶
- The circuit breaker pattern. Use on async functions that may fail often, such as requests to an unreliable server.Instances can be used as decorators, unless instantiated with a function as the first parameter, in which case the decorated function is returned.Construct a circuit breaker, whose circuit is initially closed.If
nameis passed, use it as its name; return a function wrappingfotherwise, deriving the name of the circuit breaker from the function. This derivation follows exactly one level of__wrapped__-based wrapping after retrieving the__func__attribute if present.Pass exceptions that are expected to happen through theexcparameter.When the decorated function fails more thanmax_failstimes (defaultCIRCUIT_BREAKER_DEFAULT_MAX_FAILS), the breaker triggers (opens the circuit, so to say) and disallows further calls of the wrapped functions by throwing an exception.This state persists until theresettimeout expires (defaultCIRCUIT_BREAKER_DEFAULT_RESET). Then, the breaker enters the half-open state.If the function completes successfully when the breaker is half-open undermax_half_open_calls(defaultCIRCUIT_BREAKER_DEFAULT_MAX_HALF_OPEN_CALLS) tries, the circuit closes automatically. Otherwise, the circuit reopens.- class State¶
Bases:
enum.IntEnumEnum where members are also (and must be) ints
Initialize self. See help(type(self)) for accurate signature.
- CLOSED = 0¶
The closed state.
- HALF_OPEN = 1¶
The half-open state.
- OPEN = 2¶
The open state.
- __call__[T, **P](
- f: collections.abc.Callable[P, collections.abc.Awaitable[T]],
- /,
- *,
- timer: asyncutils._internal.prots.Timer = ...,
- default: T = ...,
- Apply the circuit breaker to a function
freturning an awaitable, and return a wrapper function with the same signature that strictly returns coroutines.timer(defaulttime.monotonic()) is used to get the current time to calculate the timeout.If passed,defaultis returned if an expected exception is raised, also suppressing that exception.Caution
Care should be taken when applying the same circuit breaker to multiple functions, as the calls counters will be shared.
- class asyncutils.altlocks.DynamicThrottle(
- init_rate: float,
- min_rate: float = ...,
- max_rate: float = ...,
- window: int | None = ...,
- *,
- ubound: float | None = ...,
- lbound: float | None = ...,
- ufactor: float | None = ...,
- lfactor: float | None = ...,
- jitter: float | None = ...,
- timer: asyncutils._internal.prots.Timer = ...,
- rand: collections.abc.Callable[[float], float] = ...,
Limit the rate of a function being called.
init_rate(required): The initial rate in calls per second.min_rate: The minimum rate; defaultDYNAMIC_THROTTLE_DEFAULT_MIN_RATE.max_rate: The maximum rate; defaultDYNAMIC_THROTTLE_DEFAULT_MAX_RATE.window: Number of calls, successful or unsuccessful, after which the rate is automatically adjusted; defaultDYNAMIC_THROTTLE_DEFAULT_WINDOW.ubound: Lower bound of the ratio (successes: total calls) such that the rate is multiplied byufactor(defaultDYNAMIC_THROTTLE_DEFAULT_UFACTOR) and clamped tomin_rateandmax_rate; defaultDYNAMIC_THROTTLE_DEFAULT_UBOUND.lbound: Upper bound of the above ratio such that the rate is multiplied bylfactor(defaultDYNAMIC_THROTTLE_DEFAULT_LFACTOR) and clamped similarly; defaultDYNAMIC_THROTTLE_DEFAULT_LBOUND.jitter: The jitter in calculation of the wait time before the context can enter; defaultDYNAMIC_THROTTLE_DEFAULT_JITTER.timer: Function to return current time as a float.rand: Function that takes a float (the jitter) and returns a random number within the intervaljitterand-jitter.
- async __aenter__() None[source]¶
Wait for the time as computed by the throttler, with some jitter applied, to pass, such that the rate is maintained.
- async __aexit__(exc_typ: asyncutils._internal.prots.ExcType, exc_val: BaseException, exc_tb: types.TracebackType, /) None[source]¶
- async __aexit__(exc_typ: None, exc_val: None, exc_tb: None, /) None
If an error caused the context manager, increment
failsand re-raise; otherwise, incrementsuccesses. Also adjust the rate if necessary.
- property ctime: ty_extensions.JustFloat¶
The current time as returned by
timer.
- class asyncutils.altlocks.Releasing(lock: asyncutils._internal.prots.AsyncLockLike[object], /)[source]¶
Essentially invert the roles of the async enter and exit methods of a lock.
Instantiate the async context manager to release
lockon entry and re-acquires it on exit.- async __aenter__() None[source]¶
Call the release method of the lock, awaiting if it returns a coroutine.
- async __aexit__(exc_typ: asyncutils._internal.prots.ExcType, exc_val: BaseException, exc_tb: types.TracebackType, /) None[source]¶
- async __aexit__(exc_typ: None, exc_val: None, exc_tb: None, /) None
Re-enter the lock, propagating errors.
- class asyncutils.altlocks.ResourceGuard[T][source]¶
Bases:
asyncutils.mixins.AsyncContextMixin[None]A sync- and async-compatible context manager, inspired by
anyio.ResourceGuard, which causes contention of a shared resource to fail fast.Tip
A strong reference to the object will be held for the lifetime of the guard.
Note
The guard is not held upon creation.
actionis used in error messages to describe the action being attempted on the resource, such as'access'or'close'.rsrcis used in error messages to describe the resource by calling its__repr__(); if not passed, an index is automatically assigned to the resource.- __enter__() None[source]¶
- Throw
ResourceBusyif the resource is already being guarded.Otherwise, mark the resource as guarded, such thatguardedevaluates toTrue.
- __exit__(exc_typ: asyncutils._internal.prots.ExcType, exc_val: BaseException, exc_tb: types.TracebackType, /) None[source]¶
- __exit__(exc_typ: None, exc_val: None, exc_tb: None, /) None
Mark the resource as no longer guarded.
- yields_resource() asyncutils._internal.prots.DualContextManager[T][source]¶
Return a one-off context manager serving the same purpose as the guard but giving the resource on entry.
- class asyncutils.altlocks.StatefulBarrier[T](parties: int, name: str = ..., *, max_state: int | None = ...)[source]¶
- class asyncutils.altlocks.StatefulBarrier(
- parties: int,
- *,
- init_state: asyncutils._internal.prots.SupportsIteration[T],
- max_state: int | None = ...,
- class asyncutils.altlocks.StatefulBarrier(
- parties: int,
- name: str,
- init_state: asyncutils._internal.prots.SupportsIteration[T],
- max_state: int | None = ...,
Bases:
asyncutils.mixins.AwaitableMixin[tuple[int,collections.deque[T]]]An async barrier, that unlike traditional barriers, accumulates state from parties in a deque and makes it available once the barrier is tripped.
parties(required): The number of parties required to break the barrier.name: The name of the barrier, to appear in error messages.init_state: An iterable storing the initial state. The iterable will be exhausted eventually.max_state: Maximum length of state to store. Older state will be expelled.
- async abort() None[source]¶
Abort the barrier, signalling
BrokenBarrierErrorto present waiting parties.
- raise_for_abort() None[source]¶
Throw
BrokenBarrierErrorif the barrier has been aborted.
- async wait(state: T = ..., timeout: float | None = ...) tuple[int, collections.deque[T]][source]¶
- Note that the calling party is waiting for the barrier, optionally adding some state.If the barrier has already been aborted or broken, raise
BrokenBarrierError.Once enough parties are waiting, all callers receive a tuple(pos, states), wherestatesis the deque of stored state andposthe number of parties having arrived before this one.
- class asyncutils.altlocks.UniqueResourceGuard[T: collections.abc.Hashable][source]¶
Bases:
ResourceGuard[T]A subclass of
ResourceGuardthat only allows one guard per object. Cannot be further subclassed.Note
You must keep the guard alive for as long as you want the resource to be guarded.
Caution
This class does not stop the object from having an instance of
ResourceGuard(or subclass thereof) from guarding it simultaneously.Implementation detail
Instances are weakly referenceable.
If the object already has a guard, return that guard, regardless of whether it is held. In that case, theactionparameter is ignored and a warning is issued.Otherwise, create and return a new guard for the object, using theactionparameter in error messages.Attention
The error will be seen by the user only when they actually try to acquire the guard if it is already held.