Skip to content

pr/refactor getbody retry ci#18

Merged
KingPin merged 11 commits intomainfrom
pr/refactor-getbody-retry-ci
Mar 10, 2026
Merged

pr/refactor getbody retry ci#18
KingPin merged 11 commits intomainfrom
pr/refactor-getbody-retry-ci

Conversation

@KingPin
Copy link
Owner

@KingPin KingPin commented Mar 10, 2026

  • fix(sendRequest): handle nil GetBody, close response on retry, and constant-format logging
  • test: use closed localhost port for deterministic network-error test
  • docs: add copilot instructions and docker-only + atomic commits guidance
  • refactor: pre-read request body when GetBody missing; improve retry detection (net/url errors)

Copilot AI review requested due to automatic review settings March 10, 2026 17:24
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR improves request retry robustness in the FanOut Go service by handling GetBody being nil, tightening retryable-network-error detection, and making CI/tests more deterministic, with accompanying documentation updates.

Changes:

  • Update multiplex/sendRequest to better support retries when GetBody is nil (pre-read body) and to close responses on retry.
  • Improve retryability detection using typed net.Error / url.Error checks and adjust logging calls to use constant formats.
  • Add/adjust tests for deterministic network errors and GetBody-nil scenarios; update Docker CI steps and add repo Copilot instructions.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
fanout.go Adds body pre-read fallback when GetBody is nil; improves retry error detection and retry cleanup; adjusts logging usage.
fanout_test.go Makes the network-error test deterministic by using a closed localhost port.
fanout_additional_test.go Adds tests for multiplex handling without GetBody and for retryable net.Error.
.github/workflows/docker-image.yml Runs formatting/vet, gosec, and tests inside Docker in CI.
.github/copilot-instructions.md Documents repo-specific build/test conventions and workflow preferences.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

fanout.go Outdated
@@ -527,7 +556,7 @@ func sendRequest(ctx context.Context, client *http.Client, target string, origin
resp.Status = http.StatusInternalServerError
resp.Error = fmt.Sprintf("Failed to create request: %v", err)
bodyReader.Close()
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

bodyReader can be nil when getBody == nil, but on http.NewRequestWithContext error you unconditionally call bodyReader.Close(), which will panic. Guard the close with a nil check (or avoid closing here and rely on Transport when Do is called).

Suggested change
bodyReader.Close()
if bodyReader != nil {
bodyReader.Close()
}

Copilot uses AI. Check for mistakes.
run: |
go mod download
go test -v ./...
docker run --rm -v ${{ github.workspace }}:/src -w /src golang:1.24 sh -c "gofmt -l . || true; go vet ./... || true"
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

This step masks failures: go vet ./... || true will always succeed even when vet finds issues, and gofmt -l . won’t fail the job when files are unformatted. Make the step fail on vet/gofmt findings (e.g., remove || true for vet and explicitly error when gofmt -l outputs any files).

Suggested change
docker run --rm -v ${{ github.workspace }}:/src -w /src golang:1.24 sh -c "gofmt -l . || true; go vet ./... || true"
docker run --rm -v ${{ github.workspace }}:/src -w /src golang:1.24 sh -c 'set -e
fmt_output=$(gofmt -l .)
if [ -n "$fmt_output" ]; then
echo "gofmt found unformatted files:"
echo "$fmt_output"
exit 1
fi
go vet ./...'

Copilot uses AI. Check for mistakes.
Comment on lines +26 to +31
// Create a request WITHOUT GetBody (http.NewRequest leaves GetBody nil)
body := []byte("hello")
req, err := http.NewRequest("POST", "/fanout", bytes.NewReader(body))
if err != nil {
t.Fatalf("Failed to create request: %v", err)
}
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

This test claims http.NewRequest leaves GetBody nil, but for common in-memory body types like *bytes.Reader Go sets GetBody automatically. As written, this may not exercise the getBody == nil branch in multiplex; consider explicitly clearing req.GetBody or using a body type that doesn’t trigger automatic GetBody generation.

Suggested change
// Create a request WITHOUT GetBody (http.NewRequest leaves GetBody nil)
body := []byte("hello")
req, err := http.NewRequest("POST", "/fanout", bytes.NewReader(body))
if err != nil {
t.Fatalf("Failed to create request: %v", err)
}
// Create a request and explicitly clear GetBody to simulate a request without it
body := []byte("hello")
req, err := http.NewRequest("POST", "/fanout", bytes.NewReader(body))
if err != nil {
t.Fatalf("Failed to create request: %v", err)
}
req.GetBody = nil // ensure GetBody is nil so multiplex exercises the no-GetBody path

Copilot uses AI. Check for mistakes.
@KingPin KingPin merged commit d7bcb3e into main Mar 10, 2026
1 check passed
@KingPin KingPin deleted the pr/refactor-getbody-retry-ci branch March 10, 2026 20:28
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