2016-10-17 53 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