Exponential backoff is an algorithm that uses feedback to multiplicatively decrease the rate of some process, in order to gradually find an acceptable rate. These algorithms find usage in a wide range of systems and processes, with radio networks and computer networks being particularly notable.
간단하게 일정 시간 간격을 두고 Retry를 한다고 생각해보자. 이 경우도 일정 시간의 여유를 줬지 사실 동일하게 네트워크 부하를 줄 가능성이 크다. 그래서 일반적인 방법은 점진적으로 시간 간격이 늘어나는 Exponential Backoff 전략을 사용하는 것이다. 이 경우 지수에 비례하여 Backoff 시간을 조절한다. 예를 들어 첫번째 재시도를 위한 대기 시간은 100ms, 두번째 재시도를 위한 대기시간은 200ms, 세번째 재시도를 위한 대기시간은 400ms 처럼 2의 지수배만큼 늘어나는 방식이다.
import random
import time
from functools import wraps
class ThrottledException(Exception):
pass
def retry(ExceptionToCheck, tries=4, delay=3, backoff=2, logger=None):
def deco_retry(f):
@wraps(f)
def f_retry(*args, **kwargs):
mtries, mdelay = tries, delay
while mtries >= 1:
try:
return f(*args, **kwargs)
except ExceptionToCheck:
msg = f"{mdelay}초 후 재시도 예정...."
if logger:
logger.error(msg) # would print stack trace
else:
print(msg)
time.sleep(mdelay)
mtries -= 1
mdelay *= backoff
return f(*args, **kwargs)
return f_retry # true decorator
return deco_retry
@retry(ThrottledException, tries=5, delay=0.5,backoff=1.3)
def main():
try:
rnd = random.random()
if rnd < 0.5:
response = {"error": "Too Many Requests"}
raise ThrottledException(response)
response = {"response":"created"}
print(response)
return response
except ThrottledException as e:
print(f"에러 : {e}")
raise ThrottledException(e)
except Exception as e:
print("Generic Exception")
main()