2016-10-17 63 views
2

我试图在金字塔视图中运行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

金字塔框架与asyncio不兼容,没有理由一起使用它们。 –

+0

我有一种感觉,它可能是这样的。我仍然感兴趣为什么?我注意到uWSGI服务器有一个使用asyncio的实验性功能,这是否会改变它的行为? – sdk900

+0

编号金字塔是一个WSGI框架。 WSGI由标准定义同步。 –

回答

2

要调用您的视图,以便清楚地loop.run_until_complete它会阻止,直到完成!

如果你想使用WSGI应用程序的asyncio,那么你需要在另一个线程中这样做。例如,您可以启动一个包含eventloop的线程并执行您的异步代码。 WSGI代码全部是同步的,所以任何异步代码都必须以这种方式完成,这有它自己的问题,或者你可以忍受它阻塞请求线程,就像你现在正在做的那样。

+0

我其实确实可以阻止。由于我在代码中的非天真示例在文件列表上运行了一个子进程。每个文件都有不同的大小,并且会有不同的处理时间。因此,并行执行任务是完成这项工作的有效方式。 – sdk900