Moved a bunch of stuff from api to greenthread and imported into __init__. Broke circular import in timer.py.
This commit is contained in:
@@ -11,6 +11,11 @@ sleep = greenthread.sleep
|
|||||||
spawn = greenthread.spawn
|
spawn = greenthread.spawn
|
||||||
spawn_n = greenthread.spawn_n
|
spawn_n = greenthread.spawn_n
|
||||||
Event = greenthread.Event
|
Event = greenthread.Event
|
||||||
|
call_after_global = greenthread.call_after_global
|
||||||
|
call_after_local = greenthread.call_after_local
|
||||||
|
TimeoutError = greenthread.TimeoutError
|
||||||
|
exc_after = greenthread.exc_after
|
||||||
|
with_timeout = greenthread.with_timeout
|
||||||
|
|
||||||
GreenPool = greenpool.GreenPool
|
GreenPool = greenpool.GreenPool
|
||||||
GreenPile = greenpool.GreenPile
|
GreenPile = greenpool.GreenPile
|
||||||
|
@@ -8,6 +8,7 @@ import warnings
|
|||||||
|
|
||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
from eventlet.hubs import get_hub as get_hub_, get_default_hub as get_default_hub_, use_hub as use_hub_
|
from eventlet.hubs import get_hub as get_hub_, get_default_hub as get_default_hub_, use_hub as use_hub_
|
||||||
|
from eventlet import greenthread
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'call_after', 'exc_after', 'getcurrent', 'get_default_hub', 'get_hub',
|
'call_after', 'exc_after', 'getcurrent', 'get_default_hub', 'get_hub',
|
||||||
@@ -37,10 +38,6 @@ def switch(coro, result=None, exc=None):
|
|||||||
|
|
||||||
Greenlet = greenlet.greenlet
|
Greenlet = greenlet.greenlet
|
||||||
|
|
||||||
class TimeoutError(Exception):
|
|
||||||
"""Exception raised if an asynchronous operation times out"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def tcp_listener(address, backlog=50):
|
def tcp_listener(address, backlog=50):
|
||||||
"""
|
"""
|
||||||
@@ -80,6 +77,7 @@ def connect_tcp(address, localaddr=None):
|
|||||||
desc.connect(address)
|
desc.connect(address)
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
|
TimeoutError = greenthread.TimeoutError
|
||||||
|
|
||||||
def trampoline(fd, read=None, write=None, timeout=None, timeout_exc=TimeoutError):
|
def trampoline(fd, read=None, write=None, timeout=None, timeout_exc=TimeoutError):
|
||||||
"""Suspend the current coroutine until the given socket object or file
|
"""Suspend the current coroutine until the given socket object or file
|
||||||
@@ -118,7 +116,6 @@ def trampoline(fd, read=None, write=None, timeout=None, timeout_exc=TimeoutError
|
|||||||
t.cancel()
|
t.cancel()
|
||||||
|
|
||||||
|
|
||||||
from eventlet import greenthread
|
|
||||||
spawn = greenthread.spawn
|
spawn = greenthread.spawn
|
||||||
spawn_n = greenthread.spawn_n
|
spawn_n = greenthread.spawn_n
|
||||||
|
|
||||||
@@ -186,80 +183,9 @@ class timeout(object):
|
|||||||
if typ is _SilentException and value in self.throw_args:
|
if typ is _SilentException and value in self.throw_args:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def with_timeout(seconds, func, *args, **kwds):
|
with_timeout = greenthread.with_timeout
|
||||||
"""Wrap a call to some (yielding) function with a timeout; if the called
|
|
||||||
function fails to return before the timeout, cancel it and return a flag
|
|
||||||
value.
|
|
||||||
|
|
||||||
:param seconds: seconds before timeout occurs
|
exc_after = greenthread.exc_after
|
||||||
:type seconds: int or float
|
|
||||||
:param func: the callable to execute with a timeout; must be one of the
|
|
||||||
functions that implicitly or explicitly yields
|
|
||||||
:param \*args: positional arguments to pass to *func*
|
|
||||||
:param \*\*kwds: keyword arguments to pass to *func*
|
|
||||||
:param timeout_value: value to return if timeout occurs (default raise
|
|
||||||
:class:`~eventlet.api.TimeoutError`)
|
|
||||||
|
|
||||||
:rtype: Value returned by *func* if *func* returns before *seconds*, else
|
|
||||||
*timeout_value* if provided, else raise ``TimeoutError``
|
|
||||||
|
|
||||||
:exception TimeoutError: if *func* times out and no ``timeout_value`` has
|
|
||||||
been provided.
|
|
||||||
:exception *any*: Any exception raised by *func*
|
|
||||||
|
|
||||||
**Example**::
|
|
||||||
|
|
||||||
data = with_timeout(30, httpc.get, 'http://www.google.com/', timeout_value="")
|
|
||||||
|
|
||||||
Here *data* is either the result of the ``get()`` call, or the empty string if
|
|
||||||
it took too long to return. Any exception raised by the ``get()`` call is
|
|
||||||
passed through to the caller.
|
|
||||||
"""
|
|
||||||
# Recognize a specific keyword argument, while also allowing pass-through
|
|
||||||
# of any other keyword arguments accepted by func. Use pop() so we don't
|
|
||||||
# pass timeout_value through to func().
|
|
||||||
has_timeout_value = "timeout_value" in kwds
|
|
||||||
timeout_value = kwds.pop("timeout_value", None)
|
|
||||||
error = TimeoutError()
|
|
||||||
timeout = exc_after(seconds, error)
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
return func(*args, **kwds)
|
|
||||||
except TimeoutError, ex:
|
|
||||||
if ex is error and has_timeout_value:
|
|
||||||
return timeout_value
|
|
||||||
raise
|
|
||||||
finally:
|
|
||||||
timeout.cancel()
|
|
||||||
|
|
||||||
|
|
||||||
def exc_after(seconds, *throw_args):
|
|
||||||
"""Schedule an exception to be raised into the current coroutine
|
|
||||||
after *seconds* have elapsed.
|
|
||||||
|
|
||||||
This only works if the current coroutine is yielding, and is generally
|
|
||||||
used to set timeouts after which a network operation or series of
|
|
||||||
operations will be canceled.
|
|
||||||
|
|
||||||
Returns a :class:`~eventlet.timer.Timer` object with a
|
|
||||||
:meth:`~eventlet.timer.Timer.cancel` method which should be used to
|
|
||||||
prevent the exception if the operation completes successfully.
|
|
||||||
|
|
||||||
See also :func:`~eventlet.api.with_timeout` that encapsulates the idiom below.
|
|
||||||
|
|
||||||
Example::
|
|
||||||
|
|
||||||
def read_with_timeout():
|
|
||||||
timer = api.exc_after(30, RuntimeError())
|
|
||||||
try:
|
|
||||||
httpc.get('http://www.google.com/')
|
|
||||||
except RuntimeError:
|
|
||||||
print "Timed out!"
|
|
||||||
else:
|
|
||||||
timer.cancel()
|
|
||||||
"""
|
|
||||||
return call_after(seconds, getcurrent().throw, *throw_args)
|
|
||||||
|
|
||||||
|
|
||||||
sleep = greenthread.sleep
|
sleep = greenthread.sleep
|
||||||
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from eventlet import hubs
|
from eventlet import hubs
|
||||||
|
from eventlet import timer
|
||||||
from eventlet.support import greenlets as greenlet
|
from eventlet.support import greenlets as greenlet
|
||||||
|
|
||||||
__all__ = ['getcurrent', 'sleep', 'spawn', 'spawn_n', 'call_after_global', 'call_after_local', 'GreenThread', 'Event']
|
__all__ = ['getcurrent', 'sleep', 'spawn', 'spawn_n', 'call_after_global', 'call_after_local', 'GreenThread', 'Event']
|
||||||
@@ -80,6 +81,87 @@ def call_after_local(seconds, function, *args, **kwargs):
|
|||||||
|
|
||||||
call_after = call_after_local
|
call_after = call_after_local
|
||||||
|
|
||||||
|
class TimeoutError(Exception):
|
||||||
|
"""Exception raised if an asynchronous operation times out"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def exc_after(seconds, *throw_args):
|
||||||
|
"""Schedule an exception to be raised into the current coroutine
|
||||||
|
after *seconds* have elapsed.
|
||||||
|
|
||||||
|
This only works if the current coroutine is yielding, and is generally
|
||||||
|
used to set timeouts after which a network operation or series of
|
||||||
|
operations will be canceled.
|
||||||
|
|
||||||
|
Returns a :class:`~eventlet.timer.Timer` object with a
|
||||||
|
:meth:`~eventlet.timer.Timer.cancel` method which should be used to
|
||||||
|
prevent the exception if the operation completes successfully.
|
||||||
|
|
||||||
|
See also :func:`~eventlet.api.with_timeout` that encapsulates the idiom below.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
def read_with_timeout():
|
||||||
|
timer = api.exc_after(30, RuntimeError())
|
||||||
|
try:
|
||||||
|
httpc.get('http://www.google.com/')
|
||||||
|
except RuntimeError:
|
||||||
|
print "Timed out!"
|
||||||
|
else:
|
||||||
|
timer.cancel()
|
||||||
|
"""
|
||||||
|
if seconds is None: # dummy argument, do nothing
|
||||||
|
return timer.Timer(seconds, lambda: None)
|
||||||
|
hub = hubs.get_hub()
|
||||||
|
return hub.schedule_call_local(seconds, getcurrent().throw, *throw_args)
|
||||||
|
|
||||||
|
|
||||||
|
def with_timeout(seconds, func, *args, **kwds):
|
||||||
|
"""Wrap a call to some (yielding) function with a timeout; if the called
|
||||||
|
function fails to return before the timeout, cancel it and return a flag
|
||||||
|
value.
|
||||||
|
|
||||||
|
:param seconds: seconds before timeout occurs
|
||||||
|
:type seconds: int or float
|
||||||
|
:param func: the callable to execute with a timeout; must be one of the
|
||||||
|
functions that implicitly or explicitly yields
|
||||||
|
:param \*args: positional arguments to pass to *func*
|
||||||
|
:param \*\*kwds: keyword arguments to pass to *func*
|
||||||
|
:param timeout_value: value to return if timeout occurs (default raise
|
||||||
|
:class:`~eventlet.api.TimeoutError`)
|
||||||
|
|
||||||
|
:rtype: Value returned by *func* if *func* returns before *seconds*, else
|
||||||
|
*timeout_value* if provided, else raise ``TimeoutError``
|
||||||
|
|
||||||
|
:exception TimeoutError: if *func* times out and no ``timeout_value`` has
|
||||||
|
been provided.
|
||||||
|
:exception *any*: Any exception raised by *func*
|
||||||
|
|
||||||
|
**Example**::
|
||||||
|
|
||||||
|
data = with_timeout(30, httpc.get, 'http://www.google.com/', timeout_value="")
|
||||||
|
|
||||||
|
Here *data* is either the result of the ``get()`` call, or the empty string if
|
||||||
|
it took too long to return. Any exception raised by the ``get()`` call is
|
||||||
|
passed through to the caller.
|
||||||
|
"""
|
||||||
|
# Recognize a specific keyword argument, while also allowing pass-through
|
||||||
|
# of any other keyword arguments accepted by func. Use pop() so we don't
|
||||||
|
# pass timeout_value through to func().
|
||||||
|
has_timeout_value = "timeout_value" in kwds
|
||||||
|
timeout_value = kwds.pop("timeout_value", None)
|
||||||
|
error = TimeoutError()
|
||||||
|
timeout = exc_after(seconds, error)
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
return func(*args, **kwds)
|
||||||
|
except TimeoutError, ex:
|
||||||
|
if ex is error and has_timeout_value:
|
||||||
|
return timeout_value
|
||||||
|
raise
|
||||||
|
finally:
|
||||||
|
timeout.cancel()
|
||||||
|
|
||||||
|
|
||||||
def _spawn_n(seconds, func, args, kwargs):
|
def _spawn_n(seconds, func, args, kwargs):
|
||||||
hub = hubs.get_hub()
|
hub = hubs.get_hub()
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from eventlet.api import getcurrent
|
from eventlet.support import greenlets as greenlet
|
||||||
from eventlet.hubs import get_hub
|
from eventlet.hubs import get_hub
|
||||||
|
|
||||||
""" If true, captures a stack trace for each timer when constructed. This is
|
""" If true, captures a stack trace for each timer when constructed. This is
|
||||||
@@ -74,7 +74,7 @@ class Timer(object):
|
|||||||
class LocalTimer(Timer):
|
class LocalTimer(Timer):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.greenlet = getcurrent()
|
self.greenlet = greenlet.getcurrent()
|
||||||
Timer.__init__(self, *args, **kwargs)
|
Timer.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Reference in New Issue
Block a user