fix(exec): avoid flaky async subprocess timeouts
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
@@ -91,26 +93,31 @@ class ExecTool(Tool):
|
|||||||
env["PATH"] = env.get("PATH", "") + os.pathsep + self.path_append
|
env["PATH"] = env.get("PATH", "") + os.pathsep + self.path_append
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = await asyncio.create_subprocess_shell(
|
with tempfile.TemporaryFile() as stdout_file, tempfile.TemporaryFile() as stderr_file:
|
||||||
command,
|
process = subprocess.Popen(
|
||||||
stdout=asyncio.subprocess.PIPE,
|
command,
|
||||||
stderr=asyncio.subprocess.PIPE,
|
stdout=stdout_file,
|
||||||
cwd=cwd,
|
stderr=stderr_file,
|
||||||
env=env,
|
cwd=cwd,
|
||||||
)
|
env=env,
|
||||||
|
shell=True,
|
||||||
try:
|
|
||||||
stdout, stderr = await asyncio.wait_for(
|
|
||||||
process.communicate(),
|
|
||||||
timeout=effective_timeout,
|
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
|
||||||
process.kill()
|
deadline = asyncio.get_running_loop().time() + effective_timeout
|
||||||
try:
|
while process.poll() is None:
|
||||||
await asyncio.wait_for(process.wait(), timeout=5.0)
|
if asyncio.get_running_loop().time() >= deadline:
|
||||||
except asyncio.TimeoutError:
|
process.kill()
|
||||||
pass
|
try:
|
||||||
return f"Error: Command timed out after {effective_timeout} seconds"
|
process.wait(timeout=5.0)
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
pass
|
||||||
|
return f"Error: Command timed out after {effective_timeout} seconds"
|
||||||
|
await asyncio.sleep(0.05)
|
||||||
|
|
||||||
|
stdout_file.seek(0)
|
||||||
|
stderr_file.seek(0)
|
||||||
|
stdout = stdout_file.read()
|
||||||
|
stderr = stderr_file.read()
|
||||||
|
|
||||||
output_parts = []
|
output_parts = []
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user