тайм-аут ayncio в методе ожидания объяснить

>>> import asyncio
>>> help(asyncio.wait)

..

Help on function wait in module asyncio.tasks:

wait(fs, *, loop=None, timeout=None, return_when='ALL_COMPLETED')
    Wait for the Futures and coroutines given by fs to complete.

    Coroutines will be wrapped in Tasks.

    Returns two sets of Future: (done, pending).

    Usage:

        done, pending = yield from asyncio.wait(fs)

    Note: This does not raise TimeoutError! Futures that aren't done
    when the timeout occurs are returned in the second set.
(END)

Я не совсем понимаю последнее примечание в этой справке (что такое второй набор? он находится в ожидании/повторной обработке? как мне выполнить ожидающие задачи и объединить результаты как выполненных, так и ожидающих, а затем сохранить в БД)

Моя проблема: я использую asyncio с aiohttp, у меня миллионы URL-адресов, некоторые из них могут вызвать ошибку тайм-аута. Я хочу отправить их в очередь на повторную обработку, или об этом должен позаботиться пул событий.

import asyncio
import aiohttp
sem = asyncio.Semaphore(10)

def process_data(url):
    with (yield from sem):
          response = yield from aiohttp.request('GET', url)
          print(response)

loop = asyncio.get_event_loop()
c = asyncio.wait([process_data(url) for url in url_list], timeout=10)
loop.run_until_complete(c)

PS: я не использую метод wait_for.


person micheal    schedule 03.03.2015    source источник


Ответы (1)


Вот два набора из справки:

Returns two sets of Future: (done, pending).

Второй набор — это набор pending, задания, которые не были завершены в течение тайм-аута. Он вернет кортеж с двумя списками фьючерсов, один из которых выполнен, а другой еще не выполнен.

вместо:

c = asyncio.wait([process_data(url) for url in url_list], timeout=10)
loop.run_until_complete(c)

вам, вероятно, следует:

def dostuff():
    done, pending = yield from asyncio.wait([process_data(url) for url in url_list], timeout=10)

    # do something with pending

loop.run_until_complete(dostuff())

Вот дополнительная информация:

https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.wait

person leech    schedule 03.03.2015
comment
Я также хочу запускать ожидающие задачи (асинхронно). как я могу снова пройти в event_loop)? - person micheal; 04.03.2015
comment
@michael Незавершенные задачи продолжают выполняться после истечения тайм-аута wait. Они не отменены, не прерваны или что-то в этом роде. Таким образом, для их повторного планирования не требуется никакой операции — они будут продолжать работать в фоновом режиме, пока вы не остановите цикл обработки событий. - person dano; 17.03.2015