def sync(*func, timeout=None):
"""
coroutine decorator, convert a coroutine into a syncronous function::
@sync(timeout=2)
async def main(sleep_for):
await uvio.sleep(sleep_for)
return 'main returned ok!'
print(main(1))
"""
if not func:
return partial(sync, timeout=timeout)
func = func[0]
@wraps(func)
def inner(*args, **kwargs):
loop = Loop.create(func.__name__)
coro = func(*args, **kwargs)
if not iscoroutine(coro):
raise Exception("{} is not a coroutine (returned from {})".format(coro, func))
loop.next_tick(coro)
if timeout:
def stop_loop():
loop.stop()
raise Exception("timeout")
timer = loop.set_timeout(stop_loop, timeout)
# Don't wait for the timout to exit the loop
timer.unref()
loop.run()
loop.close()
if timeout:
timer.close()
if coro.cr_await is not None:
coro.throw(Exception('coroutine {} should not be running at the end of the loop'.format(coro)))
# This should not happend
assert not loop._awaiting, loop._awaiting
assert not loop.ready, loop.ready
return inner
评论列表
文章目录