I'd like to be able to set timeout on subprocess stdout and return an empty string if exceeded timeout.
Here's my attempt to do so using asyncio.
However, it failed on using file.stdout.readline() in asyncio.wait_for.
Any idea how to fix this ?
import threading
import select
import subprocess
import queue
import time
import asyncio
class collector():
@staticmethod
async def readline(file, timeout=3):
try:
line = await asyncio.wait_for(file.stdout.readline(), timeout)
except asyncio.TimeoutError:
return ""
else:
return line
@staticmethod
async def background(command):
f = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
while True:
line = await collector.readline(file=f, timeout=3)
asyncio.run(collector.background("tail -f /tmp/2222"))
And here's callstack :
File "/tmp/script.py", line 13, in readline
line = await asyncio.wait_for(file.stdout.readline(), timeout)
File "/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py", line 462, in wait_for
fut = ensure_future(fut, loop=loop)
File "/usr/local/Cellar/python@3.9/3.9.6/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/tasks.py", line 679, in ensure_future
raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required