Использование asyncio.create_subprocess_shell в каналах Django Consumer - PullRequest
0 голосов
/ 11 сентября 2018

Всякий раз, когда клиент (т.е. потребитель) подключается к моему серверу Django, я хочу выполнить команду в командной строке, а затем распечатать код возврата команды:

from channels.generic.websocket import AsyncWebsocketConsumer
import asyncio

class Consumer(AsyncWebsocketConsumer):
    async def do_command(self):
        process = await asyncio.create_subprocess_shell('pwd', stdout=asyncio.subprocess.PIPE)
        try:
            line = await asyncio.wait_for(process.stdout.readline(), 5)
            print("line is" + line.decode())
            print(process.returncode)
            # wait for process to finish so we can check the return code
            await asyncio.wait_for(process.wait(), 5)
        except asyncio.TimeoutError:
            print("process timed out!")
        else:
            print("process finished successfully!")
        finally:
            print(process.returncode)

    async def connect(self):
        asyncio.get_event_loop().create_task(self.do_command())
        print("Finished scheduling do_command task")

Когда я запускаю приведенный выше код, я получаю

Finished scheduling do_command task
line is /opt/working_dir/django
None
process timed out!
None

всякий раз, когда клиент подключается к моему серверу.

Однако process.returncode всегда None

Почему это? Мне нужно знать, была ли команда выполнена успешно или нет.

Проблема, похоже, связана именно с await process.wait. По какой-то причине команда никогда не завершает выполнение (то есть process.returncode всегда None).

Тем не менее, следующий код работает нормально:

import asyncio
async def do_command():
    process = await asyncio.create_subprocess_shell(cmd='pwd')
    await process.wait()
    print("Finished process.wait")
    print(process.returncode)

loop = asyncio.get_event_loop()
task = loop.create_task(do_command())
asyncio.get_event_loop().run_until_complete(task)
loop.close()
print("Finished Go Task")

возвращается:

/opt/working_dir/django
Finished process.wait
0
Finished Go Task
...