我正在尝试在 Pyramid View 中运行异步子流程,但 View 挂起并且异步任务似乎永远无法完成。我可以在 Pyramid View 之外运行这个示例并且它可以工作。
话虽如此,我最初使用loop = asyncio.get_event_loop()
进行了测试,但这告诉我RuntimeError:线程“Dummy-2”中没有当前事件循环
这里肯定有一些我不完全理解的事情。也许 View 线程与主线程不同,所以 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
最佳答案
您正在 View 中调用loop.run_until_complete
,因此很明显它将被阻止直到完成!
如果您想在 WSGI 应用程序中使用 asyncio,那么您需要在另一个线程中执行此操作。例如,您可以启动一个包含事件循环的线程并执行异步代码。 WSGI 代码都是同步的,因此任何异步代码都必须以这种方式完成,但有其自身的问题,或者您可以像现在一样忍受它阻塞请求线程。
关于pyramid - 在 Pyramid View 中使用 Asyncio 子流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40081144/