在Python中使用Pebble重新启动/重建超时进程?

时间:2019-03-08 18:36:57

标签: python concurrency concurrent.futures

我正在使用并发期货来使用API​​从远程服务器下载报告。为了通知我该报告已正确下载,我只需要打印其ID即可。

我遇到一个问题,报告下载很少会无限期地挂起。我没有收到超时错误或连接重置错误,只是挂了几个小时直到我杀死了整个过程。这是API的已知问题,没有解决方法。

我做了一些研究,并转而使用基于Pebble的方法来实现该函数的超时。然后,我的目的是记录未能下载并重新启动的报告的ID。

很遗憾,我遇到了一些麻烦,因为我不知道如何实际检索未能下载的报告的ID。我使用的布局类似于this答案:

from pebble import ProcessPool
from concurrent.futures import TimeoutError

def sometimes_stalling_download_function(report_id):
    ...
    return report_id

with ProcessPool() as pool:
    future = pool.map(sometimes_stalling_download_function, report_id_list, timeout=10)

    iterator = future.result()

    while True:
        try:
            result = next(iterator)
        except StopIteration:
            break
        except TimeoutError as error:
            print("function took longer than %d seconds" % error.args[1])
            #Retrieve report ID here
            failed_accounts.append(result)

我想做的是在发生超时的情况下检索报告ID,但似乎无法从该异常中获取报告ID。在超时异常的情况下,是否仍可以使函数输出ID,还是我不得不重新考虑如何完全下载报告?

1 个答案:

答案 0 :(得分:0)

map函数返回一个future对象,该对象产生的结果与提交顺序相同。

因此,要了解是哪个report_id导致了超时,您只需检查其在report_id_list中的位置即可。

index = 0

while True:
    try:
        result = next(iterator)
    except StopIteration:
        break
    except TimeoutError as error:
        print("function took longer than %d seconds" % error.args[1])
        #Retrieve report ID here
        failed_accounts.append(report_id_list[index])
    finally:
        index += 1