Skip to content

Commit 0ebe6cc

Browse files
authored
fix(release-tool): add HTTP client timeout configuration for large changelog queries (#167)
Fixes HTTP/2 stream cancellation errors when generating changelogs for releases with large number of commits (500+). The default http.DefaultClient has a 30-second idle timeout which causes "stream error: stream ID X; CANCEL; received from peer" errors when the GitHub GraphQL API takes longer to respond with large datasets. Changes: - Add configured HTTP client to GQLClient struct - Set 5-minute overall timeout for GraphQL requests - Set 2-minute response header timeout - Set 90-second idle connection timeout - Replace http.DefaultClient with configured client in graphqlQuery() This resolves issues when generating changelogs between versions with hundreds of commits (e.g., 2.12.0 to 2.13.0 with 557 commits). Refs: https://github.com/kumahq/kuma/actions/runs/20373037604 Signed-off-by: Marcin Skalski <skalskimarcin33@gmail.com>
1 parent 2a9b2c9 commit 0ebe6cc

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

cmd/internal/github/graphql.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,9 @@ func (r GQLRefTarget) Commit() string {
127127
}
128128

129129
type GQLClient struct {
130-
Token string
131-
Cl *github.Client
130+
Token string
131+
Cl *github.Client
132+
httpClient *http.Client
132133
}
133134

134135
func SplitRepo(repo string) (string, string) {
@@ -146,7 +147,19 @@ func NewGQLClient(useGHAuth bool) (*GQLClient, error) {
146147

147148
cl := github.NewClient(nil).WithAuthToken(token)
148149

149-
return &GQLClient{Token: token, Cl: cl}, nil
150+
// Configure HTTP client with appropriate timeouts for large GraphQL queries
151+
// This prevents stream cancellation errors when fetching large changelogs
152+
httpClient := &http.Client{
153+
Timeout: 5 * time.Minute,
154+
Transport: &http.Transport{
155+
ResponseHeaderTimeout: 2 * time.Minute,
156+
ExpectContinueTimeout: 1 * time.Second,
157+
// Increase idle connection timeout for long-running queries
158+
IdleConnTimeout: 90 * time.Second,
159+
},
160+
}
161+
162+
return &GQLClient{Token: token, Cl: cl, httpClient: httpClient}, nil
150163
}
151164

152165
func (c GQLClient) ReleaseGraphQL(repo string) ([]GQLRelease, error) {
@@ -295,7 +308,7 @@ func (c GQLClient) graphqlQuery(query string, variables map[string]interface{})
295308
r.Header.Set("Authorization", fmt.Sprintf("bearer %s", c.Token))
296309
r.Header.Set("Content-Type", "application/json")
297310
var res *http.Response
298-
res, err = http.DefaultClient.Do(r)
311+
res, err = c.httpClient.Do(r)
299312
if err != nil {
300313
return out, err
301314
}

0 commit comments

Comments
 (0)