Skip to content

feat: Add a command to stop the local stack - #5

Merged
nfebe merged 2 commits into
mainfrom
feat/stop-stack
Sep 7, 2026
Merged

feat: Add a command to stop the local stack#5
nfebe merged 2 commits into
mainfrom
feat/stop-stack

Conversation

@nfebe

@nfebe nfebe commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Add a stop command for the local stack. Requires an agent release with shutdown support.

@sourceant-local

sourceant-local Bot commented Sep 7, 2026

Copy link
Copy Markdown

Code Review Summary

This revision implements the requested sourceant stop support. The agent client now sends Accept: application/json, handles the stop response with a switch, and exposes IsConnectionRefused. The command uses that helper, and tests cover success, unsupported status codes, and timeout behavior.

🚀 Key Improvements

  • Refactored internal/agent/client.go to use a switch for status-code handling, as previously suggested.
  • Added Accept: application/json to the stop request for consistency with other client methods.
  • Added agent.IsConnectionRefused so the command package no longer imports syscall directly.
  • Strengthened internal/command/stop_test.go to assert the unsupported-agent error message and added a timeout-vs-refused test.

💡 Minor Suggestions

  • Clarify the comment in internal/agent/client.go so it covers 200, 404, and 405.
  • Add a doc comment for the exported IsConnectionRefused helper.
  • Tighten the timeout test assertion to check for the specific error substring.

@sourceant-local sourceant-local Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review complete. See the overview comment for a summary.

Comment thread internal/agent/client.go Outdated
Comment thread internal/command/stop_test.go

@sourceant-local sourceant-local Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Review complete. See the overview comment for a summary.

Comment thread internal/agent/client.go
switch resp.StatusCode {
case http.StatusNoContent:
return nil
case http.StatusOK, http.StatusNotFound, http.StatusMethodNotAllowed:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The comment only explains the 200 case, but this branch also groups 404 and 405. Update it to describe all three unsupported statuses so future readers don't wonder why NotFound/MethodNotAllowed are handled here.

Suggested change
case http.StatusOK, http.StatusNotFound, http.StatusMethodNotAllowed:
case http.StatusOK, http.StatusNotFound, http.StatusMethodNotAllowed:
// Only 204 acknowledges shutdown; 200/404/405 mean this agent does not support stop.

Comment thread internal/agent/client.go

func (e *Unreachable) Unwrap() error { return e.Cause }

func IsConnectionRefused(err error) bool {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Exported functions should have a doc comment explaining their contract, especially since this is a new public helper used by the command package.

Suggested change
func IsConnectionRefused(err error) bool {
// IsConnectionRefused reports whether err represents an agent that is not
// listening because the connection was refused.
func IsConnectionRefused(err error) bool {
var unreachable *Unreachable
return errors.As(err, &unreachable) && errors.Is(unreachable.Cause, syscall.ECONNREFUSED)
}

if Run([]string{"--agent", server.URL, "--timeout", "20ms", "stop"}, &out, &stderr) == 0 {
t.Fatal("a timed-out stop request succeeded")
}
if strings.Contains(out.String(), "already stopped") || stderr.Len() == 0 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Checking that stderr is non-empty is weak. Assert the actual error message so the test fails with a clear diagnostic if the wrong error path is taken (for example, if a future change prints "already stopped" to stderr instead of stdout).

Suggested change
if strings.Contains(out.String(), "already stopped") || stderr.Len() == 0 {
if strings.Contains(out.String(), "already stopped") || !strings.Contains(stderr.String(), "could not stop SourceAnt") {
t.Fatalf("stdout=%s stderr=%s", out.String(), stderr.String())
}

@nfebe
nfebe merged commit 00e8105 into main Sep 7, 2026
3 checks passed
@nfebe
nfebe deleted the feat/stop-stack branch September 8, 2026 23:12
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.

1 participant