在應用中,有時候會 依賴第三方模塊執行方法,好比調用某模塊的上傳下載,數據庫查詢等操做的時候,若是出現網絡問題或其餘問題,可能有超時從新請求的狀況;html
目前的解決方案有python
1. 信號量,但不支持window;數據庫
2.多線程,可是 若是是大量的數據重複操做嘗試,會出現線程管理混亂,開啓上萬個線程的問題;網絡
3.結合採用 eventlet 和 retrying模塊 (eventlet 原理尚需深刻研究)多線程
下面的方法實現:超過指定時間從新嘗試某個方法dom
# -*- coding: utf-8 -*- import random import time import eventlet from retrying import retry eventlet.monkey_patch() class RetryTimeOutException(Exception): def __init__(self, *args, **kwargs): pass def retry_if_timeout(exception): """Return True if we should retry (in this case when it's an IOError), False otherwise""" return isinstance(exception, RetryTimeOutException) def retry_fun(retries=3, timeout_second=2): """ will retry ${retries} times when process time beyond ${timeout_second} ; :param retries: The retry times :param timeout_second: The max process time """ def retry_decor(func): @retry(stop_max_attempt_number=retries, retry_on_exception=retry_if_timeout) def decor(*args, **kwargs): print("In retry method..") pass_flag = False with eventlet.Timeout(timeout_second, False): r = func(*args, **kwargs) pass_flag = True print("Success after method.") if not pass_flag: raise RetryTimeOutException("Time out..") print("Exit from retry.") return r return decor return retry_decor def do_request(): print("begin request...") sleep_time = random.randint(1, 4) print("request sleep time: %s." % sleep_time) time.sleep(sleep_time) print("end request...") return True @retry_fun(retries=3) def retry_request(): r = do_request() print(r) if __name__ == '__main__': retry_request()
參考:this
安裝依賴模塊:pip install retrying eventlet -i https://pypi.tuna.tsinghua.edu.cn/simple/.net
裝飾器用法:https://blog.csdn.net/u013205877/article/details/78872278線程
retry: https://blog.csdn.net/lxy210781/article/details/952530263d
超時:https://blog.csdn.net/yuanpython/article/details/90522567
其餘方法:https://www.cnblogs.com/lyxdw/p/10033118.html