-
Notifications
You must be signed in to change notification settings - Fork 3
Description
Problem
In both GetGraph (internal/api/client.go:285-296) and GetCircularDependencies (internal/api/client.go:416-426), the multipart body is constructed inside the polling loop. On every retry attempt, the entire repo zip is re-serialized into a new multipart body:
for attempt := 0; attempt < maxPollAttempts; attempt++ {
var body bytes.Buffer
mw := multipart.NewWriter(&body)
fw.Write(repoZip) // copies the full zip on every attempt
...
}
With maxPollAttempts = 90 and a repo zip up to 10 MB, this can mean copying up to 900 MB of data across retries, with a fresh allocation on each pass. The multipart body content is identical every time since both the idempotency key and zip data are constant across the loop.
Fix
Build the multipart body once before the loop, capture it as a []byte, and use bytes.NewReader on each attempt so the reader can be reset:
// Build once
var bodyBuf bytes.Buffer
mw := multipart.NewWriter(&bodyBuf)
...
mw.Close()
bodyBytes := bodyBuf.Bytes()
contentType := mw.FormDataContentType()
for attempt := 0; attempt < maxPollAttempts; attempt++ {
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(bodyBytes))
...
}
This applies to both GetGraph and GetCircularDependencies.
Affected files
- internal/api/client.go:274-395 (GetGraph polling loop)
- internal/api/client.go:400-528 (GetCircularDependencies polling loop)
@claude please implement this