在金字塔视图中使用Asyncio子流程

时间:2016-10-17 07:55:44

标签: pyramid python-3.5 python-asyncio

我正在尝试在金字塔视图中运行asyncio子流程,但视图挂起,异步任务似乎永远不会完成。我可以在金字塔视图之外运行这个例子,它可以工作。

据说我最初使用loop = asyncio.get_event_loop()进行了测试,但这告诉我RuntimeError: There is no current event loop in thread 'Dummy-2'

我肯定不会完全明白这里的事情。也许视图线程与主线程不同,因此get_event_loop不起作用。

那么有人知道为什么我的异步任务可能不会在这种情况下产生结果吗?这是一个天真的例子。

@asyncio.coroutine
def async_task(dir):
    # This task can be of varying length for each handled directory
    print("Async task start")
    create = asyncio.create_subprocess_exec(
        'ls',
        '-l',
        dir,
        stdout=asyncio.subprocess.PIPE)
    proc = yield from create

    # Wait for the subprocess exit
    data = yield from proc.stdout.read()
    exitcode = yield from proc.wait()
    return (exitcode, data)


@view_config(
    route_name='test_async',
    request_method='GET',
    renderer='json'
)
def test_async(request):
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    dirs = ['/tmp/1/', '/tmp/2/', '/tmp/3/']
    tasks = []
    for dir in dirs:
        tasks.append(asyncio.ensure_future(async_task(dir), loop=loop))

    loop.run_until_complete(asyncio.gather(*tasks))
    loop.close()
    return

1 个答案:

答案 0 :(得分:2)

您正在视图中调用loop.run_until_complete,所以很明显它会一直阻止直到完成!

如果要将asyncio与WSGI应用程序一起使用,则需要在另一个线程中执行此操作。例如,您可以启动包含eventloop的线程并执行您的异步代码。 WSGI代码都是同步的,所以任何异步代码都必须以这种方式完成,它有自己的问题,或者你可以像它现在一样阻止请求线程。