Lasier
A sync/async circuit breaker implementation
According to Nygard on your masterpiece book Release It!:
[...] circuit breakers protect overeager gadget hounds from burning their houses down. The principle is the same: detect excess usage, fail first, and open the circuit. More abstractly, the circuit breaker exists to allow one subsystem (an electrical circuit) to fail (excessive current draw, possibly from a short circuit) without destroying the entire system (the house). Furthermore, once the danger has passed, the circuit breaker can be reset to restore full function to the system.
Requirements
- Python >= 3.7
Instalation
Using pip:
pip install lasier
Usage
To use lasier circuit breaker you'll need a rule and a cache (the circuit state storage) instance
Rule
A Rule is the mechanism that define where circuit will open or close.
MaxFailuresRule
Rule to open circuit based on maximum number of failures
from lasier.circuit_breaker.rules import MaxFailuresRule
rule = MaxFailuresRule(
max_failures=500,
failure_cache_key='my_cb'
)
Arguments
| Argument | Definition |
|---|---|
| max_failures | Maximum number of errors |
| failure_cache_key | Cache key where the number of errors is incremented |
PercentageFailuresRule
Rule to open circuit based on a percentage of failures
from lasier.circuit_breaker.rules import PercentageFailuresRule
rule = PercentageFailuresRule(
max_failures_percentage=60,
failure_cache_key='my_cb',
min_accepted_requests=100,
request_cache_key='my_cb_request'
)
Arguments
| Argument | Definition |
|---|---|
| max_failures_percentage | Maximum percentage of errors |
| failure_cache_key | Cache key where the number of errors is incremented |
| min_accepted_requests | Minimum number of requests accepted to not open circuit breaker |
| request_cache_key | Cache key where the number of requests is incremented |
Circuit Breaker
You can use the Lasier circuit breaker with a context_manager f.ex:
from lasier.circuit_breaker.sync import CircuitBreaker
...
def some_protected_func():
with CircuitBreaker(
rule=rule,
cache=cache,
failure_exception=ValueError,
catch_exceptions=(KeyError, TypeError)
):
# some process
Or a decorator, f.ex:
from lasier.circuit_breaker.asyncio import circuit_breaker
...
@circuit_breaker(
rule=rule,
cache=cache,
failure_exception=ValueError,
catch_exceptions=(KeyError, TypeError)
)
async def some_protected_func():
# some process
The sync and async implementations follow the same interface, so you only need to change the import path:
lasier.circuit_breaker.sync: for sync implementataionlasier.circuit_breaker.asyncio: for async implementataion
Arguments
| Argument | Definition |
|---|---|
| rule | Instance of class rule. |
| cache | Instance of the circuit breaker state storage. |
| failure_exception | Exception to be raised when it exceeds the maximum number of errors and when the circuit is open. |
| failure_timeout | This value is set on first error. It is used to validate the number of errors by time. (seconds, default 60) |
| circuit_timeout | Time that the circuit will be open. (seconds, default 60) |
| catch_exceptions | List of exceptions catched to increase the number of errors. |
WARNING: The args
failure_timeoutandcircuit_timeoutwill be used on state storage commands so if you'll use libs that expects milliseconds instead of seconds ontimeoutarguments maybe you'll get yourself in trouble
Circuit state storage
Lasier works with a storage to register the current state of the circuit, number of failures, etc. That storage respects the follow interface:
from lasier.types import Timeout # Timeout = Optional[Union[int, float]]
class Storage:
def add(self, key: str, value: int, timeout: Timeout = None) -> None:
pass
def set(self, key: str, value: int, timeout: Timeout = None) -> None:
pass
def incr(self, key: str) -> int:
pass
def get(self, key: str) -> int:
pass
def expire(key: str, timeout: Timeout = None) -> None:
pass
def delete(self, key: str) -> None:
pass
def flushdb(self) -> None:
pass
For
asynccircuit breaker, lasier works with that same interface however with async syntax, f.ex:async def set(self, key=str, value=int, timeout=Optional[int])
So you can use any cache/storage that respects that interface.
Adapters
If you'll use Lasier with redis-py as cache, you can use lasier.adapters.caches.redis.RedisAdapter
from lasier.adapters.caches import RedisAdapter
from redis import Redis
cache = RedisAdapter(Redis(host='localhost', port=6479, db=0))
Implemented Adapters
| Lib | Adapter |
|---|---|
| redis-py | lasier.adapters.caches.RedisAdapter |
| django-cache | lasier.adapters.caches.DjangoAdapter |
| django-cache-async | lasier.adapters.caches.DjangoAsyncAdapter |
| aiocache | lasier.adapters.caches.AiocacheAdapter |
Metadata
Release files for lasier 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lasier-0.3.0.tar.gz | 9.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lasier-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.5 kB
Release files / lasier-0.3.0.tar.gz
| Download URL | lasier-0.3.0.tar.gz |
|---|---|
| Size | 9.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
03d5a8058adc1ff1f0d17f9e544b946bd8c6d7256dfe120288022677fc2db8ce
|
|
BLAKE2b-256 checksum How to use checksums |
8c5d9672792e0712fbbc5a3d24f9d3128e9ee53ab5a79ba204c14bc352bba679
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.14 CPython/3.7.13 Linux/5.15.0-1014-azure
|
Release files / lasier-0.3.0-py3-none-any.whl
| Download URL | lasier-0.3.0-py3-none-any.whl |
|---|---|
| Size | 11.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68a8218aead4a9b1ad33aaed9085575dcc128076432a0d6837cfbf214ff958f9
|
|
BLAKE2b-256 checksum How to use checksums |
97991437761145080028c5a2363b23326e3140e16f10226c53fccae0269e1f42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.1.14 CPython/3.7.13 Linux/5.15.0-1014-azure
|