I have a program that has to unconditionally respond after X seconds, that response can either be the actual response i need if under X seconds or some sort of "Gathering resources, please wait" message if the time has passed.
How can i do something along the lines of
make request
start timer
if request.responded:
return request
if timer.hasPassed(X):
return False
While still having the request active, ready to respond as soon as it is finished?
CodePudding user response:
You seem to be looking for asyncio.wait_for
. It accepts a coroutine and a timeout
parameter, awaits the coroutine and raises asyncio.TimeoutError
(as well as cancelling the coroutine) if the timeout period is exceeded. More here.
async def eternity():
# Sleep for one hour
await asyncio.sleep(3600)
print('yay!')
async def main():
# Wait for at most 1 second
try:
await asyncio.wait_for(eternity(), timeout=1.0)
except asyncio.TimeoutError:
print('timeout!')
If you want to keep the coroutine running after the timeout and eventually get its result you need to create a task and shield it from cancellation:
async def long_running_task():
await asyncio.sleep(5)
return True
async def main():
task = asyncio.create_task(long_running_task())
try:
return await asyncio.wait_for(asyncio.shield(task), timeout=1)
except asyncio.TimeoutError:
print('Time out')
return await task