Im asyncio-Modell wird die Ausführung durch eine Ereignisschleife geplant und koordiniert. Um die Ausführung einer aktuell ausgesetzten Aufgabe abzubrechen, müssen Sie im Wesentlichen einfach es nicht fortsetzen. Während dies in der Praxis ein wenig anders funktioniert, sollte es offensichtlich sein, dass dies die Aufhebung einer suspendierten Aufgabe in der Theorie einfach macht.
Individuelle Timeouts sind auf die gleiche Art und Weise möglich: Wann immer Sie eine Coroutine anhalten, um auf ein Ergebnis zu warten, möchten Sie einen Timeout-Wert angeben. Die Ereignisschleife stellt sicher, dass die wartende Aufgabe abgebrochen wird, wenn diese Zeitüberschreitung erreicht ist und die Aufgabe noch nicht abgeschlossen ist.
Einige konkrete Beispiele:
>>> 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
In der Praxis könnte dies so etwas wie dies implementiert werden:
class Foo:
task = None
async def sleeper(self):
self.task = asyncio.sleep(60)
try:
await self.task
except concurrent.futures.CancelledError:
raise NotImplementedError
Während diese Methode schläft, kann foo.task.cancel()
jemand anderes rufen Sie die Koroutine aufwachen und lass es mit der Stornierung umgehen. Alternativ kann der Anruf sleeper()
es direkt stornieren, ohne ihm eine Chance zu geben, aufzuräumen.
Timeouts einstellen ähnlich ist einfach:
>>> loop.run_until_complete(asyncio.wait_for(asyncio.sleep(60), 5))
[ ... 5 seconds later ... ]
Traceback (most recent call last):
...
concurrent.futures._base.TimeoutError
Insbesondere im Zusammenhang mit der HTTP-Request-Timeouts finden 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'))
Offensichtlich jeder Aufruf fetch_page
auf seinem eigenen aiohttp.Timeout
Wert entscheiden können, und Jede einzelne Instanz wird eine eigene Ausnahme auslösen, wenn diese Zeitüberschreitung erreicht ist.
Um der Selbsteindämmung, können Sie diese anderen zwei Fragen hier zusammenfassen? – deceze
@deceze, habe ich die Frage aktualisiert und meine Schlussfolgerung hinzugefügt. Ist das ok oder fehlt noch etwas? – guettli
Sieht jetzt antwortbarer aus, danke. – deceze