Асинхронная фоновая обработка с помощью Flask? - PullRequest
0 голосов
/ 07 ноября 2018

У меня есть процесс, который я хочу вызвать через конечную точку http, который будет запускать асинхронные процессы (почти как в пакетном режиме).

без функциональности сервера, мой код:

async def run(cmd):
    proc = await asyncio.create_subprocess_shell(
        cmd,
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE)

    stdout, stderr = await proc.communicate()

    print(f'[{cmd!r} exited with {proc.returncode}]')
    if stdout:
        if proc.returncode == 0:
            print(f'[stdout]\n{Fore.GREEN}{stdout.decode()}{Style.RESET_ALL}!')
        else:
            print(f'[stdout]\n{Fore.RED}{stdout.decode()}{Style.RESET_ALL}!')
    if stderr:
        print(f'[stderr]\n{Fore.RED}{stderr.decode()}{Style.RESET_ALL}!')

тогда я могу вызвать подпроцесс через:

async def abar():
    await asyncio.gather(
        run('python3 --version') #literally ANY long process
       #that i need to call
    )

оттуда я могу сделать:

asyncio.run (abar ())

и мое приложение успешно работает. Моей целью было поставить часть asyncio.run за конечной точкой колбы:

@app.route("/batch")
def e2e():
    asyncio.run(abar())
    return 'OK'

однако, при этом, похоже, возникают ошибки:

Невозможно добавить дочерний обработчик, к дочернему наблюдателю не присоединен цикл

Каков наилучший способ инициировать асинхронные вызовы подпроцесса через некоторую конечную точку http?

Я пытался использовать subprocess.call, но это не похоже на асинхронность ...

1 Ответ

0 голосов
/ 08 ноября 2018

Я смог решить эту проблему, используя subprocess.Popen

вместо

async def abar():
    await asyncio.gather(
        run('python3 --version') #literally ANY long process
       #that i need to call
    )

Я сделал:

async def abar():
   Popen(['pyton3', '--version']) # or any long process

и в фактическом маршруте колбы:

@app.route("/batch")
    def e2e():
       abar()
...