Implementation of the CircuitBreaker Pattern in Python, popularized by Michael T. Nygard in his book Release It!
This app is intended to run at minimum Python version 3.6. Extra requirements can be seen in requirements.txt file.
It is possible to customize the application to set custom values for the application by the environment variables.
Environment Variables usages as following:
ENV | Default Value | TYPE | Description |
---|---|---|---|
HTTP_CLIENT |
sqlite |
string |
Address to be tested by circuitbreaker. Format <HOST>:<PORT> |
ERROR_THRESHOLD |
3 |
int |
Treshold in seconds of failed attempts to identify the circuit as opened |
TIME_WINDOW |
10 |
int |
Time in seconds between remote calls |
ACCEPT_CLIENT_ERRORS |
False |
bool |
True to Accept 3XX and 4XX return codes, False to accept 3XX |
LOG_LEVEL |
INFO |
string |
Verbosity of log. Values: INFO , DEBUG , WARNING , ERROR |
To deploy it locally its suggested to set up a venv.
Clone the repository:
$ git clone [email protected]:caiodelgadonew/circuitbreaker-py.git
Create a Virtual Environment and source it:
$ python3 -m venv circuitbreakerpy
$ source circuitbreakerpy/bin/activate
After initializing your Virtual Environment install all dependencies
$ pip3 install -r app/requirements.txt
Execute the application
$ HTTP_CLIENT=<HOST>:<PORT> python3 circuitbreaker.py
A docker-compose file is available which will run an nginx server and also the circuitbreaker application, in that way it is possible to simulate the http errors with it.
To run the application as a Docker Container you can use the provided docker-compose.yml
Be sure to have docker and docker-compose installed before proceeding
Clone the repository:
$ git clone [email protected]:caiodelgadonew/circuitbreaker-py.git
Run docker-compose up
to create the environment:
$ docker-compose up
You can add
-d
to thedocker-compose
command to start detached
Attach to the logs of the circuitbreaker
container:
$ docker-compose logs -f circuitbreaker
To simulate the OpenCircuitError
, open a new terminal and stop the nginx
container
$ docker-compose stop nginx
The circuitbreaker will start to show the CircuitOpenError
, the circuit will be opened until the HTTP_CLIENT
is available again.
circuitbreaker-py | 2022-07-17 09:33:23 INFO __main__: Remote Call Succeded
circuitbreaker-py | 2022-07-17 09:33:30 ERRO __main__: CircuitOpenError - Remote Call has failed for 1 consecutive times.
circuitbreaker-py | 2022-07-17 09:33:37 ERRO __main__: CircuitOpenError - Remote Call has failed for 2 consecutive times.
circuitbreaker-py | 2022-07-17 09:33:44 ERRO __main__: CircuitOpenError - Remote Call has failed for 3 consecutive times.
circuitbreaker-py | 2022-07-17 09:33:44 INFO __main__: Circuit changed from closed to open
circuitbreaker-py | 2022-07-17 09:33:51 ERRO __main__: CircuitOpenError - Remote Call has failed for 4 consecutive times.
circuitbreaker-py | 2022-07-17 09:33:58 ERRO __main__: CircuitOpenError - Remote Call has failed for 5 consecutive times.
Now you can start again the nginx container
$ docker-compose start nginx
The circuitbreaker will start the recovering process, going from open
to half_open
state, and as soon as the ERROR_THRESHOLD
is less than the success rate, it will change to closed
state again.
circuitbreaker-py | 2022-07-17 09:35:22 ERRO __main__: CircuitOpenError - Remote Call has failed for 17 consecutive times.
circuitbreaker-py | 2022-07-17 09:35:26 INFO __main__: Circuit changed from open to half_open
circuitbreaker-py | 2022-07-17 09:35:26 INFO __main__: Remote Call has succeeded for 1 consecutive times.
circuitbreaker-py | 2022-07-17 09:35:28 INFO __main__: Remote Call has succeeded for 2 consecutive times.
circuitbreaker-py | 2022-07-17 09:35:30 INFO __main__: Remote Call has succeeded for 3 consecutive times.
circuitbreaker-py | 2022-07-17 09:35:32 INFO __main__: Remote Call has succeeded for 4 consecutive times.
circuitbreaker-py | 2022-07-17 09:35:32 INFO __main__: Circuit changed from half_open to closed
circuitbreaker-py | 2022-07-17 09:35:34 INFO __main__: Remote Call Succeded
circuitbreaker-py | 2022-07-17 09:35:36 INFO __main__: Remote Call Succeded