【问题标题】:How to retry x times and put a long sleep with a print如何重试 x 次并打印长时间睡眠
【发布时间】:2021-05-29 13:59:43
【问题描述】:

我一直试图了解backoff 的工作原理。我的目标是每当我达到 status_code 等:405 5 次。我想休眠 60000 秒并打印出出现状态错误 405。

现在我已经写了:

import time

import backoff
import requests

@backoff.on_exception(
    backoff.expo,
    requests.exceptions.RequestException,
    max_tries=5,
    giveup=lambda e: e.response is not None and e.response.status_code == 405
)
def publish(url):
    r = requests.post(url, timeout=10)
    r.raise_for_status()


publish("https://www.google.se/")

现在发生的情况是,如果它只达到 405 一次,它将引发 status_code 并停止脚本。我正在寻找的是如何让脚本重试 5 次,如果状态是 405 连续 5 次,那么我们想要长时间睡眠并打印出来。如何使用 backofF 做到这一点?我也有其他建议:)

旧式计数器:

    import requests
    import time
    from requests.exceptions import ConnectionError, ReadTimeout, RequestException, Timeout
    
    exception_counter = 0
    
    while True:
    
        try:
            response = requests.get("https://stackoverflow.com/", timeout=12)
    
            if response.ok:
                print("Very nice")
                time.sleep(60)
    
            else:
                print(
                    f'[Response -> {response.status_code}]'
                    f'[Response Url -> {response.url}]'
                )
                time.sleep(60)
    
                if response.status_code == 403:
                    if exception_counter >= 10:
                        print("Hit limitation of counter: Response [403]")
                        time.sleep(4294968)
    
                    exception_counter += 1
    
        
    except (ConnectionError) as err:
        print(err)
        time.sleep(random.randint(1, 3))
        
        if exception_counter >= 10:
            print(f"Hit limitation of coonnectionerror {err}")
            time.sleep(4294968)
            continue
        
        exception_counter += 1
        continue
        
    except (ReadTimeout, Timeout) as err:
        print(err)
        time.sleep(random.randint(1, 3))
        continue

    except RequestException as err:
        print(err)
        time.sleep(random.randint(1, 3))
        continue

    except Exception as err:
        print(err)
        time.sleep(random.randint(1, 3))
        
        if exception_counter >= 10:
            print(f"Hit limitation of Exception {err}")
            time.sleep(4294968)
            continue
        
        exception_counter += 1
        continue

【问题讨论】:

    标签: python python-3.x if-statement exception


    【解决方案1】:

    你没有说在睡眠 60000 秒后你想做什么,所以我将它设置为在四次尝试后睡眠,然后在正确失败之前进行最后一次(第五次)尝试。

    您可以使用on_backoff 处理程序添加您所要求的自定义逻辑。

    我还重新调整了你的 giveup 函数,你可能把布尔值弄错了。

    import time
    import backoff
    import requests
    
    
    def backoff_hdlr(details):
        print("backoff_hdlr", details)
        if details["tries"] >= 4:
            print(f"sleeping")
            time.sleep(1)  # 60000
    
    
    @backoff.on_exception(
        backoff.expo,
        requests.exceptions.RequestException,
        max_tries=5,
        giveup=lambda e: e.response.status_code != 405,
        on_backoff=backoff_hdlr,
    )
    def publish(url):
        print(f"called publish with url={url}")
        r = requests.post(url, timeout=10)
        r.raise_for_status()
    
    
    publish("https://www.google.se/")
    
    /Users/michael/.conda/envs/mip_typing/bin/python /Users/michael/git/mip_typing/scratch_2.py
    called publish with url=https://www.google.se/
    backoff_hdlr {'target': <function publish at 0x7fe45c626b80>, 'args': ('https://www.google.se/',), 'kwargs': {}, 'tries': 1, 'elapsed': 1.5e-05, 'wait': 0.8697943681459608}
    called publish with url=https://www.google.se/
    backoff_hdlr {'target': <function publish at 0x7fe45c626b80>, 'args': ('https://www.google.se/',), 'kwargs': {}, 'tries': 2, 'elapsed': 1.144912, 'wait': 1.5425500028676453}
    called publish with url=https://www.google.se/
    backoff_hdlr {'target': <function publish at 0x7fe45c626b80>, 'args': ('https://www.google.se/',), 'kwargs': {}, 'tries': 3, 'elapsed': 2.949183, 'wait': 0.2052666718206697}
    called publish with url=https://www.google.se/
    backoff_hdlr {'target': <function publish at 0x7fe45c626b80>, 'args': ('https://www.google.se/',), 'kwargs': {}, 'tries': 4, 'elapsed': 3.418447, 'wait': 5.113712077372433}
    sleeping
    called publish with url=https://www.google.se/
    Traceback (most recent call last):
    ...
    
    

    【讨论】:

    • 您好!谢谢你的消息!你是对的。我没告诉。所以计划是创建一个自己的记者,它将通过短信发送给我,比如 SMS Alert 有一个问题,然后这个想法是让我睡一个超长的睡眠,直到我调查这个问题,这样睡眠 60000 或更多对我来说足够了:)
    • 但是我确实有一个问题,如果它的 status_code 403 和 Exception (Unexpected exceptions) 和 ConnectionError 也可以做类似的事情吗?我已经编辑了退避之前的情况,如果您有任何问题,请告诉我! - ÈDIT 如您所见,我想捕获一些异常以及特定的状态代码
    • 如果我想查看多个状态码,是否可以编写“自定义消息”引发状态等。我可以打印诸如“您被太多 405 击中”或 403 之类的内容吗?
    • @ProtractorNewbie 是的,你可以使用多个 on_exceptionon_predicate 装饰器来实现你想要的。也可以使用自定义异常类来帮助
    • @ProtractorNewbie 你一定能弄明白的
    猜你喜欢
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多