Skip to content

Commit

Permalink
Merge pull request #1 from pfultz2/gyield-timeout
Browse files Browse the repository at this point in the history
Add optional timeout parameter to gyield
  • Loading branch information
virtuald committed Oct 22, 2014
2 parents 8a73c42 + 67a1324 commit e892076
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
2 changes: 1 addition & 1 deletion greenado/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@

from .concurrent import gcall, generator, groutine, gyield
from .concurrent import gcall, generator, groutine, gyield, TimeoutError
from .version import __version__
12 changes: 10 additions & 2 deletions greenado/concurrent.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
from tornado import concurrent, gen
from tornado.ioloop import IOLoop

class TimeoutError(Exception):
"""Exception raised by ``gyield`` in timeout."""

def gcall(f, *args, **kwargs):
'''
Expand Down Expand Up @@ -170,7 +172,7 @@ def greenlet_base():
return wrapper


def gyield(future):
def gyield(future, timeout=None):
'''
This is functionally equivalent to the 'yield' statements used in a
:func:`@gen.coroutine <tornado.gen.coroutine>`, but doesn't require
Expand All @@ -197,8 +199,14 @@ def gyield(future):

# don't switch/wait if the future is already ready to go
if not future.done():

timeout_handle = None
if timeout != None and timeout > 0:
timeout_handle = IOLoop.current().add_timeout(
IOLoop.current().time() + timeout,
lambda: future.set_exception(TimeoutError("Timeout")))

def on_complete(result):
if timeout_handle != None: IOLoop.current().remove_timeout(timeout_handle)
gr.switch()

IOLoop.current().add_future(future, on_complete)
Expand Down
22 changes: 22 additions & 0 deletions tests/test_greenado.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from tornado import gen, concurrent
from tornado.ioloop import IOLoop
import time


class DummyException(Exception):
Expand Down Expand Up @@ -146,6 +147,27 @@ def _main():

main_result = IOLoop.current().run_sync(_main)
assert main_result == True

def test_gyield_timeout():
'''Ensure that timout throws an exception after time runs out'''

future = concurrent.Future()

def _inner():
try:
greenado.gyield(future, 2)
return 0
except greenado.TimeoutError:
return 1

@greenado.groutine
def _main():
return _inner() + 1

start_time = time.time()
main_retval = IOLoop.current().run_sync(_main)
assert main_retval == 2
assert time.time() > start_time + 2


def test_generator_error():
Expand Down

0 comments on commit e892076

Please sign in to comment.