【发布时间】:2017-06-10 01:44:06
【问题描述】:
我正在通过 asyncio.subprocess 运行外部下载器脚本,每当我尝试下载大数据时,asyncio 都会出现以下错误:
asyncio.streams.LimitOverrunError: Separator is not found, and chunk 超出限制
这是什么原因,我该如何解决?
import asyncio, subprocess, websockets, json
from os.path import expanduser, sep
async def handler(websocket, path):
print("New client connected.")
await websocket.send('CONNECTED')
path = expanduser("~") + sep
try:
while True:
inbound = await websocket.recv()
if inbound is None:
break
while inbound != None:
cmd = ('downloader_script', '-v', '-p', '-o', '/home/blah/blah', inbound)
process = await asyncio.create_subprocess_exec(*cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
async for output in process.stdout:
for line in output.decode().split('\r'):
line = line.strip()
if line == '':
continue
data = {}
await asyncio.sleep(1)
if line.startswith('INFO:'):
data['INFO'] = line.split('INFO: ')[1]
elif line.startswith('['):
data['progress'] = line.split(']')[0][1:]
elif line.startswith('ERROR:'):
data['ERROR'] = line.split('ERROR: ')[1]
else:
data['message'] = line
print (data)
await websocket.send(json.dumps(data))
await websocket.send(json.dumps({'progress': 'DONE'}))
await websocket.send('bye!')
break
except websockets.exceptions.ConnectionClosed:
print("Client disconnected.")
if __name__ == "__main__":
server = websockets.serve(handler, '0.0.0.0', 8080)
loop = asyncio.get_event_loop()
loop.run_until_complete(server)
loop.run_forever()
【问题讨论】:
-
await asyncio.sleep(1)在使用async for时不需要。我在下面更新了我的答案,举例说明如何使用tr将\r替换为\n。 -
据我了解,替换应该有效,但它没有。我想我的问题可能有点不清楚,对不起。我必须解析的输出中有一个进度条。奇怪的是,如果进度相对较短(比如 30 段),它运行良好,但如果我尝试下载更大的内容,我会在进度条处于 100% 甚至
exit(0)时得到输出。 -
但是,常规
subprocess模块并非如此,两者之间的性能差异必须是微观的,因为对我而言使用常规子进程在我的输出中至少看起来是完全异步的。 -
您的进度条进程在未发送到 tty 时可能正在缓冲其输出。
标签: python asynchronous async-await subprocess python-asyncio