Перезапуск / восстановление процесса с тайм-аутом с использованием Pebble в Python? - PullRequest
0 голосов
/ 08 марта 2019

Я использую параллельные фьючерсы для загрузки отчетов с удаленного сервера с помощью API. Чтобы сообщить мне, что отчет загружен правильно, я просто распечатал его идентификатор.

У меня есть проблема, при которой в редких случаях загрузка отчета может зависать. Я не получаю ошибку тайм-аута или ошибку сброса соединения, просто зависаю там в течение нескольких часов, пока не завершу весь процесс Это известная проблема с API без известного обходного пути.

Я провел некоторое исследование и переключился на использование подхода Pebble для реализации тайм-аута функции. Моя цель - записать идентификатор отчета, который не удалось загрузить, и начать заново.

К сожалению, я наткнулся на кирпичную стену, так как не знаю, как на самом деле получить идентификатор отчета, который мне не удалось загрузить. Я использую макет, подобный этому ответу:

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)

То, что я хочу сделать, - это получить идентификатор отчета в случае тайм-аута, но он не представляется доступным из этого исключения. Можно ли в любом случае сделать так, чтобы функция выводила идентификатор в случае исключения тайм-аута, или мне придется заново продумать, как я загружаю отчеты целиком?

1 Ответ

0 голосов
/ 23 марта 2019

Функция 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
...