Skip to content

Instantly share code, notes, and snippets.

@asvetlov
Created October 19, 2015 19:01
Show Gist options
  • Save asvetlov/ea5ca4a6f0761c4f5c75 to your computer and use it in GitHub Desktop.
Save asvetlov/ea5ca4a6f0761c4f5c75 to your computer and use it in GitHub Desktop.
import asyncio
import warnings
class Timeout:
def __init__(self, timeout, *, raise_error=False, loop=None):
self._timeout = timeout
if loop is None:
loop = asyncio.get_event_loop()
self._loop = loop
self._raise_error = raise_error
self._task = None
self._cancelled = False
self._cancel_handler = None
async def __aenter__(self):
self._task = asyncio.Task.current_task(loop=loop)
self._cancel_handler = self._loop.call_later(
self._cancel, self._timeout)
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self._cancelled:
if self._raise_error:
raise asyncio.TimeoutError
else:
# suppress
return True
else:
self._cancel_handler.cancel()
# raise all other errors
def __del__(self):
if self._task:
# just for preventing improper usage
warnings.warn("Use async with")
def _cancel(self):
self._cancelled = self._task.cancel()
async def long_running_task():
while True:
asyncio.sleep(5)
async def run():
async with Timeout(1):
await long_running_task()
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment