2016-10-17 23 views
2

Я пытаюсь запустить подпроцесс asyncio в виде пирамиды, но вид висит, и задача async, кажется, никогда не завершается. Я могу запустить этот пример вне представления пирамиды, и он работает.Использование подпроцесса 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

У меня было ощущение, что это может быть что-то вроде этого. Меня все еще интересует, почему? Я заметил, что на сервере uWSGI есть экспериментальная функция для использования asyncio, изменит ли это поведение? – sdk900

+0

№. Пирамида - это структура WSGI. WSGI является синхронным стандартным определением. –

ответ

2

Вы призываете loop.run_until_complete на ваш взгляд, так ясно, что будет не блокировать до завершения!

Если вы хотите использовать asyncio с WSGI-приложением, вам нужно сделать это в другом потоке. Например, вы можете развернуть поток, содержащий eventloop, и выполняет ваш асинхронный код. Код WSGI является синхронным, поэтому любой асинхронный код должен быть выполнен таким образом, с его собственными проблемами, или вы можете просто жить с ним, блокируя поток запросов, как сейчас.

+0

Я действительно в порядке с блокировкой. Как не наивный пример, который у меня есть в моем коде, выполняется подпроцесс в списке файлов. Каждый файл имеет разный размер и будет иметь различное время обработки. Таким образом, выполнение задачи параллельно - это эффективный способ выполнения работы. – sdk900