Skip to content

Commit a31e90c

Browse files
authored
Fix stdio transport not reading the full response (#12)
* Read stdout until newline for stdio transport Update the stdio transport to read a response from stdout until a newline or until timing out while waiting for readable data. Notably, this fixes an issue where the plugin fails when a response is more than 4096 bytes. * Add ansible-core to tox.ini mypy deps Rather than relying on ansible-core being installed outside the tox environment, install it explicitly since it's being used by tox.
1 parent abad8a5 commit a31e90c

File tree

2 files changed

+18
-14
lines changed

2 files changed

+18
-14
lines changed

plugins/plugin_utils/transport.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -123,18 +123,21 @@ def _stdout_read(self, wait_timeout: int = 5) -> dict:
123123
"""
124124

125125
response = {}
126+
buffer = b""
126127
if self._process:
127-
rfd, wfd, efd = select.select([self._process.stdout], [], [], wait_timeout)
128-
if not (rfd or wfd or efd):
129-
# Process has timeout
130-
raise AnsibleConnectionFailure(
131-
f"MCP server response timeout after {wait_timeout} seconds."
132-
)
133-
134-
if self._process.stdout in rfd:
135-
response = json.loads(
136-
os.read(self._process.stdout.fileno(), 4096).decode("utf-8").strip()
137-
)
128+
while True:
129+
rfd, wfd, efd = select.select([self._process.stdout], [], [], wait_timeout)
130+
if self._process.stdout in rfd:
131+
buffer += os.read(self._process.stdout.fileno(), 4096)
132+
if b"\n" in buffer:
133+
line, buffer = buffer.split(b"\n", 1)
134+
response = json.loads(line.decode("utf-8"))
135+
break
136+
else:
137+
# Process has timeout
138+
raise AnsibleConnectionFailure(
139+
f"MCP server response timeout after {wait_timeout} seconds."
140+
)
138141
return response
139142

140143
def _stdin_write(self, data: dict) -> None:

tox.ini

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ deps =
77
black
88
flake8
99
isort
10-
mypy
10+
{[testenv:mypy]deps}
1111
skip_install = true
1212
allowlist_externals =
1313
{[testenv:mypy]allowlist_externals}
@@ -22,13 +22,14 @@ setenv =
2222
{[testenv:mypy]setenv}
2323

2424
[testenv:mypy]
25-
deps = mypy
25+
deps =
26+
mypy
27+
ansible-core
2628
skip_install = true
2729
allowlist_externals =
2830
mkdir
2931
ln
3032
rm
31-
ansible-galaxy
3233
commands =
3334
rm -rf {toxinidir}/.collection_root
3435
ansible-galaxy collection install git+https://github.com/ansible-collections/ansible.utils.git --collections-path {toxinidir}/.collection_root

0 commit comments

Comments
 (0)