backoff 소개
[python
backoff
]
생각보다 국내 파이썬 진영에서 @backoff
에 대한 정보가 없어 여기에 기록한다.
파이썬에서 백오프는 특정 오류가 발생하면, 이를 백 오프 시켰다가 재시도를 해 주는 데코레이터이다.
먼저 사용전에 pip설치를 해야 한다
$ pip install backoff
Collecting backoff
Downloading backoff-1.11.1-py2.py3-none-any.whl (13 kB)
Installing collected packages: backoff
Successfully installed backoff-1.11.1
간단한 예제를 하나 들어 보자.
def test():
number = int(input("Enter an integer: "))
test()
실행 후 값 입력시에 int가 아닌 값을 입력하면 ValueError가 뜨게 되지만, 이를 3회정도 기회를 주고 안되면 오류를 발생시키려고 한다. 방법은 2가지가 있다.
input(...)
결과를 타입 체크를 하여 int이면 Pass, 아니면 어떤 인디케이터 변수를 두어 3이 넘어가야 오류를 발생시키게 만든다.@backoff
를 사용한다.
첫번째 방법은 코드를 많이 수정해야 하며 복잡해진다(정책과 메커니즘의 분리 원칙에도 맞지 않는다). 그래서 두 번째 방법을 쓸 것이다.
import backoff
@backoff.on_exception(backoff.expo,
ValueError,
max_tries=3)
def test():
number = int(input("Enter an integer: "))
test()
실행 결과다.
$ python3 3test.py
Enter an integer: e
Enter an integer: r
Enter an integer: t
Traceback (most recent call last):
File "3test.py", line 9, in <module>
test()
File "/home/ubuntu/.local/lib/python3.8/site-packages/backoff/_sync.py", line 94, in retry
ret = target(*args, **kwargs)
File "3test.py", line 7, in test
number = int(input("Enter an integer: "))
ValueError: invalid literal for int() with base 10: 't'
@backoff
데코레이터에서 max_tries=3 으로 입력 기회를 3회주고 계속 오류가 떨어지면 해당 오류를 발생시켰다.
이게 유용할 때는 API서버 접속이나 DB접속과 같이 서로 다른 시스템에 접속을 할 때이다. 다음은 DB접속 + HTTP request접속을 하는 특정 코드의 일부를 발췌한 것이다. (from the book “Robust Python”)
import backoff
import requests
from autokitchen.database import OperationException
# setting properties of self.*_db objects will
# update data in the database
@backoff.on_exception(backoff.expo,
OperationException,
max_tries=5)
def on_dish_ordered(dish: Dish):
self.dish_db[dish].count += 1
@backoff.on_exception(backoff.expo,
OperationException,
max_tries=5)
@backoff.on_exception(backoff.expo,
requests.exceptions.HTTPError,
max_time=60)
def save_inventory_counts(inventory):
for ingredient in inventory:
self.inventory_db[ingredient.name] = ingredient.count
첫 번째 함수 on_dish_ordered
에서의 @backoff
는 db입력이 OperationException
으로 실패하면 최대 5회까지 재시도를 하라는 것이다.
두 번째 함수인 save_inventory_counts
는 @backoff
를 중첩시켜 쓰고 있는데, DB입력 및 HTTP.request
도 사용하기 때문에 각각의 경우 재시도 조건을 정의하였다. OperationException
의 경우 5회까지 재시도를 하며, HTTPError
의 경우에는 60초동안 계속 재시도를 한다.