Cooperative Timeouts Using
- class Timeout(seconds=None, exception=None, ref=True, priority=-1)#
Raise exception in the current greenlet after seconds have elapsed:
timeout = Timeout(seconds, exception) timeout.start() try: ... # exception will be raised here, after *seconds* passed since start() call finally: timeout.close()
You must always call
Timeoutobject you have created, whether or not the code that the timeout was protecting finishes executing before the timeout elapses (whether or not the
Timeoutexception is raised) This
try/finallyconstruct or a
withstatement is a good pattern. (If the timeout object will be started again, use
close; this is rare. You must still
closeit when you are done.)
When exception is omitted or
Timeoutinstance itself is raised:
>>> import gevent >>> gevent.Timeout(0.1).start() >>> gevent.sleep(0.2) Traceback (most recent call last): ... Timeout: 0.1 seconds
If the seconds argument is not given or is
Timeout()), then the timeout will never expire and never raise exception. This is convenient for creating functions which take an optional timeout parameter of their own. (Note that this is not the same thing as a seconds value of
def function(args, timeout=None): "A function with an optional timeout." timer = Timeout(timeout) with timer: ...
A seconds value less than
-1) is poorly defined. In the future, support for negative values is likely to do the same thing as a value of
A seconds value of
0requests that the event loop spin and poll for I/O; it will immediately expire as soon as control returns to the event loop.
Use As A Context Manager
To simplify starting and canceling timeouts, the
withstatement can be used:
with gevent.Timeout(seconds, exception) as timeout: pass # ... code block ...
This is equivalent to the try/finally block above with one additional feature: if exception is the literal
False, the timeout is still raised, but the context manager suppresses it, so the code outside the with-block won’t see it.
This is handy for adding a timeout to the functions that don’t support a timeout parameter themselves:
data = None with gevent.Timeout(5, False): data = mysock.makefile().readline() if data is None: ... # 5 seconds passed without reading a line else: ... # a line was read within 5 seconds
readline()above catches and doesn’t re-raise
BaseException(for example, with a bare
except:), then your timeout will fail to function and control won’t be returned to you when you expect.
When catching timeouts, keep in mind that the one you catch may not be the one you have set (a calling function may have set its own timeout); if you going to silence a timeout, always check that it’s the instance you need:
timeout = Timeout(1) timeout.start() try: ... except Timeout as t: if t is not timeout: raise # not my timeout finally: timeout.close()
Changed in version 1.1b2: If seconds is not given or is
None, no longer allocate a native timer object that will never be started.
Changed in version 1.1: Add warning about negative seconds values.
Changed in version 1.3a1: Timeout objects now have a
close()method that must be called when the timeout will no longer be used to properly clean up native resources. The
withstatement does this automatically.
Start and return the timer. If the timer is already started, just return it.
- __exit__(typ, value, tb)#
Stop the timer.
Changed in version 1.3a1: The underlying native timer is also stopped. This object cannot be used again.
If the timeout is pending, cancel it. Otherwise, do nothing.
Close the timeout and free resources. The timer cannot be started again after this method has been used.
Schedule the timeout.
- classmethod start_new(timeout=None, exception=None, ref=True, _one_shot=False)#
Create a started
This is a shortcut, the exact action depends on timeout’s type:
- property pending#
True if the timeout is scheduled to be raised.