Skip to content

AIMVT-303: Implement HTTP client in ParallelHTTPClient class - #368

Merged
speriaswamy-amd merged 9 commits into
mainfrom
speriaswamy/aimvt-303-http-client-implementation
Sep 2, 2026
Merged

AIMVT-303: Implement HTTP client in ParallelHTTPClient class#368
speriaswamy-amd merged 9 commits into
mainfrom
speriaswamy/aimvt-303-http-client-implementation

Conversation

@speriaswamy-amd

Copy link
Copy Markdown
Contributor

Summary

  • Adds ParallelHTTPClient (cvs/core/agent/http_client.py), an async httpx-based client providing API parity with ParallelSSHClient: run_command, health, shutdown, lazy shared connection reuse, and rebuild/destroy for host-set changes.
  • Adds HostOutput dataclass and exception mapping (HTTPConnectionError/HTTPProtocolError) so unreachable vs. failed-request hosts can be distinguished the same way prune_unreachable_hosts distinguishes pssh exceptions.
  • Supports stop_on_errors, host_args (per-host command substitution), and inline/file output modes, collecting file-mode output back into list[str] for a uniform response shape.

Stacked on #365 (AIMVT-302) — this PR's diff is limited to http_client.py and its tests; base branch will be retargeted to main once #365 merges.

Jira: AIMVT-303

Test plan

  • cvs/core/agent/unittests/test_http_client.py covers run_command (inline/file/exit-code-only modes, host_args, stop_on_errors), health, shutdown, and exception classification, all against mocked HTTP transport

@atnair-amd
atnair-amd self-requested a review August 28, 2026 21:29
@speriaswamy-amd
speriaswamy-amd changed the base branch from speriaswamy/aimvt-302-http-agent-api-implementation to main August 30, 2026 20:35
@speriaswamy-amd
speriaswamy-amd force-pushed the speriaswamy/aimvt-303-http-client-implementation branch from adcf75b to bed8ee3 Compare August 30, 2026 20:37

@atnair-amd atnair-amd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes

The command-execution path is currently incompatible with the FastAPI agent: the client sends a raw JSON body without an application/json content type, and the server rejects it with HTTP 422.

Once that is corrected, the command timeout needs to be decoupled from the HTTP response deadline. An agent-side timeout can legitimately require its termination grace period before it can return an ExecResponse; the client currently reports that healthy agent as an unreachable host.

The remaining inline comments cover timeout policy for health/shutdown, FILE-mode response-path validation, connection-pool fan-out at scale, and propagation of agent execution state.

I reproduced the reported behaviors with local loopback servers and the actual FastAPI agent implementation. No existing review comments were present when this review was prepared.

Comment thread cvs/core/agent/http_client.py Outdated
Comment thread cvs/core/agent/http_client.py Outdated
Comment thread cvs/core/agent/http_client.py Outdated
Comment thread cvs/core/agent/http_client.py Outdated
Comment thread cvs/core/agent/http_client.py Outdated
Comment thread cvs/core/agent/http_client.py

@atnair-amd atnair-amd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The six prior findings are addressed in 8f6c8be1 and their threads can be resolved.

These two follow-ups are non-blocking:

  • default connect_timeout=None disables the TCP connection phase timeout;
  • positive sub-second timeouts can round to zero.

Neither affects the corrected normal command path, but both are worth addressing when tightening timeout semantics.

hosts = list(self._agent_urls)
if host_args is not None:
if len(host_args) != len(hosts):
raise ValueError(f"host_args has {len(host_args)} entries but there are {len(hosts)} hosts")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: When connect_timeout is omitted, this passes connect=None to httpx.Timeout, which disables the TCP connection deadline. That means health, shutdown, and command calls can wait for the OS-level SYN timeout rather than the selected read deadline when a host black-holes connection attempts. Please let httpx.Timeout(read_timeout) apply its finite connection phase by default, or define an explicit finite default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

response.raise_for_status()
exec_response = messages.parse_message(messages.ExecResponse, response.text)
stdout, stderr = await self._collect_output(request, exec_response)
except Exception as exc: # noqa: BLE001 - captured per-host so one bad host doesn't sink the others

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Low priority: round() turns positive fractional timeouts below 0.5 into zero. For example, read_timeout=0.4 serializes an agent process timeout of 0, immediately terminating a command that could otherwise complete. Consider rejecting non-positive rounded values or using ceil() / a minimum of one second.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

speriaswamy-amd and others added 2 commits September 1, 2026 21:56
… sub-second timeouts to zero.

Co-authored-by: Cursor <cursoragent@cursor.com>
… succeeds.

Co-authored-by: Cursor <cursoragent@cursor.com>
@speriaswamy-amd
speriaswamy-amd merged commit ae19074 into main Sep 2, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants