В модели Asyncio выполнение запланировано и координируется контуром события. Чтобы отменить выполнение приостановленной задачи, вам по существу просто нужно не возобновить. Хотя на практике это немного отличается от практики, должно быть очевидно, что это упрощает теоретическую отмену приостановленной задачи.
Индивидуальные тайм-ауты, безусловно, возможны одинаково: всякий раз, когда вы приостанавливаете сопрограмму для ожидания результата, вы хотите указать значение тайм-аута. Цикл событий будет обеспечивать отмену ожидающей задачи, когда этот тайм-аут будет достигнут, а задача еще не завершена.
Некоторые образцы бетона:
>>> import asyncio
>>> loop = asyncio.get_event_loop()
>>> task = asyncio.ensure_future(asyncio.sleep(5))
>>> task.cancel()
>>> loop.run_until_complete(task)
Traceback (most recent call last):
...
concurrent.futures._base.CancelledError
На практике это может быть реализовано с помощью что-то вроде этого:
class Foo:
task = None
async def sleeper(self):
self.task = asyncio.sleep(60)
try:
await self.task
except concurrent.futures.CancelledError:
raise NotImplementedError
Хотя этот метод спит, кто-то может назвать foo.task.cancel()
разбудить сопрограмму и пусть он справится с отменой. В качестве альтернативы, тот, кто звонит sleeper()
, может отменить его напрямую, не давая ему возможности почистить.
Настройка времени ожидания аналогично легко:
>>> loop.run_until_complete(asyncio.wait_for(asyncio.sleep(60), 5))
[ ... 5 seconds later ... ]
Traceback (most recent call last):
...
concurrent.futures._base.TimeoutError
В частности, в контексте HTTP таймаутов запроса см aiohttp:
async def fetch_page(session, url):
with aiohttp.Timeout(10):
async with session.get(url) as response:
assert response.status == 200
return await response.read()
with aiohttp.ClientSession(loop=loop) as session:
content = loop.run_until_complete(fetch_page(session, 'http://python.org'))
Очевидно каждый вызов fetch_page
может принять решение о своей собственной aiohttp.Timeout
стоимости, и каждый отдельный экземпляр будет генерировать свое собственное исключение, когда этот тайм-аут будет достигнут.
Ради самоограничения, можете ли вы обобщить эти два других вопроса здесь? – deceze
@deceze, я обновил вопрос и добавил свой вывод. Это нормально, или еще что-то не хватает? – guettli
Выглядит теперь более ответственно, спасибо. – deceze