Een async bewerking met een timeoutcontext begrenzen.
TimeoutError buiten de context herkennen en eigen opruiming behouden.
Een verlopen deadline onderscheiden van een bronfout of externe annulering.
Een bron kan een bruikbare waarde leveren, een fout melden of blijven wachten. Je wilt niet voor altijd op die laatste mogelijkheid blijven hangen. Tegelijk mag een zelfgekozen wachttijd niet alle andere manieren waarop de bewerking kan eindigen onzichtbaar maken.
Een grens rond een stuk async werk
Met asyncio.timeout maak je een async contextmanager die het wachten binnen haar blok begrenst. Het argument is een aantal seconden. Met None leg je op dat moment geen deadline vast.
De schrijfwijze lijkt op de TaskGroup uit de vorige les: async with asyncio.timeout(seconds). Binnen dat blok voer je de bewerking met await uit. Als zij op tijd terugkeert, krijg je gewoon haar werkelijke resultaat.
Een nul, lege tekst of None als resultaat betekent niet dat de tijd verstreken is. Dat kunnen geldige gegevens zijn. Laat daarom de retourwaarde intact; gebruik een aparte fout om het verlopen van de deadline aan te geven.
Het voorbeeld laat een gewone waarde door de context terugkomen. De timeout hoeft daarbij geen aparte Task-variabele of een eigen slaapteller te maken. Het begrensde blok vertelt waar de afspraak over wachten geldt.
De fout verschijnt buiten de context
Wanneer de deadline verloopt, vraagt de timeoutcontext om annulering van de huidige taak. Binnen de afgewachte bewerking werkt dat als een CancelledError. Haar eigen finally-blok kan daarom nog opruimen.
Bij het verlaten van de context wordt de door die deadline veroorzaakte annulering omgezet in TimeoutError. Vang die fout op rond het hele async with-blok als de aanroeper een alternatief wil kiezen. Een handler alleen binnen het blok staat op de verkeerde plaats voor die omzetting.
Het voorbeeld gebruikt een bewerking die op een nog niet gezette Event wacht. Er wordt niet met een stopwatch vergeleken hoeveel milliseconden de computer nodig had. De relevante uitkomst is dat de deadline het wachten beëindigt en de timeout buiten de context zichtbaar wordt.
Een deadline is geen harde afbreekknop
Ook hier blijft async code coöperatief. Een coroutine die de eventloop met een lange gewone lus bezet houdt, geeft de timeoutcallback geen gelegenheid om te lopen. En de afronding kan tijd nodig hebben om eigen opruimwerk uit te voeren.
Een timeout van nul vraagt om stoppen bij de volgende gelegenheid in de loop. Het betekent niet dat iedere regel binnen het blok onmiddellijk wordt overgeslagen. Een direct beschikbare waarde kan al terug zijn voordat de loop opnieuw aan de beurt komt.
Voor één afzonderlijke awaitable bestaat ook asyncio.wait_for(awaitable, timeout=seconds). Die wacht bij een timeout op de annulering van het bedoelde werk. Een context is prettig wanneer je de grens zichtbaar rond een groter blok wilt zetten; geef niet ongemerkt iedere deelstap een nieuw volledig budget.
Veelgemaakte fout: iedere TimeoutError zelf verzinnen
Een bron kan zelf al een TimeoutError opwerpen, bijvoorbeeld omdat zij haar eigen grens heeft bereikt. Dat is nog steeds een echte bronfout. In deze oefenfunctie laat je zulke fouten als hetzelfde exceptionobject doorgaan in plaats van een nieuwe fout met een vaste melding te maken.
Hetzelfde geldt voor een gewone ValueError. Een timeoutcontext is geen algemene foutoplosser. Alleen wachten begrenzen is geen reden om ongeldige gegevens ineens als een lege succeswaarde terug te geven.
Een stopverzoek van buiten blijft stoppen
De aanroeper kan de beheertaak zelf annuleren voordat haar deadline afloopt. De context verandert dat externe stopverzoek niet in haar eigen TimeoutError. De oorspronkelijke CancelledError gaat na de eigen opruiming door naar de aanroeper.
Alle checkpoints bekijken één functie met dit duidelijke beleid: lever echte waarden, begrens wachten met de context en laat onopgeloste fouten en externe annulering doorgaan. De meegegeven bron verzorgt haar eigen finally; jouw functie mag dat werk niet los achterlaten.
AAN DE SLAG 0/4
1
Een werkelijke waarde teruggeven
Maak async bounded_read(read_value, seconds). Voer de async bron zonder argumenten precies eenmaal uit binnen asyncio.timeout(seconds) en geef haar waarde terug. seconds is None of een niet-negatief aantal seconden. Nul, lege tekst en None kunnen geldige bronwaarden zijn.
2
Verlopen wachten zichtbaar maken
Laat bij een verstreken eigen deadline de standaard TimeoutError buiten de timeoutcontext doorgaan. De bron begint binnen de context, wacht op een gebeurtenis en voert bij annulering eerst haar eigen finally uit.
3
Een bronfout behouden
Laat gewone bronfouten, ook een door de bron zelf gemaakte TimeoutError, doorgaan als hetzelfde exceptionobject. De eigen deadline is in deze gevallen nog niet verstreken en de bron ruimt zelf op.
4
Externe annulering behouden
Laat een stopverzoek van de aanroeper als CancelledError doorgaan, ook als er een eigen toekomstige deadline is. Voordat de beheertaak klaar is, is de finally van de begonnen bron uitgevoerd.
Samenvatting
Een timeoutcontext begrenst het async werk binnen haar blok; None laat de deadline weg.
De eigen deadline wordt buiten de context een TimeoutError, na de benodigde opruiming.
Bronfouten en externe annulering blijven hun eigen uitkomst houden.
Hierna gebruik je een begrensde queue om ook de hoeveelheid wachtend werk te beheersen.