Skip to content

Commit 6718451

Browse files
committed
Fix memory leak in fleet autoscaler webhook HTTP client
- Change fasThread.state from fasState (value) to *fasState (pointer) so the cached http.Client persists across sync cycles instead of being recreated on every iteration. - Drain HTTP response body before closing to allow http.Transport to reuse connections, preventing unbounded connection growth.
1 parent ab57625 commit 6718451

3 files changed

Lines changed: 8 additions & 6 deletions

File tree

pkg/fleetautoscalers/controller.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ type fasState struct {
7272
// fasThread is used for tracking each Fleet's autoscaling jobs
7373
type fasThread struct {
7474
cancel context.CancelFunc
75-
state fasState
75+
state *fasState
7676
generation int64
7777
}
7878

@@ -360,7 +360,7 @@ func (c *Controller) syncFleetAutoscaler(ctx context.Context, key string) error
360360

361361
currentReplicas := fleet.Status.Replicas
362362
gameServerNamespacedLister := c.gameServerLister.GameServers(fleet.ObjectMeta.Namespace)
363-
desiredReplicas, scalingLimited, err := computeDesiredFleetSize(ctx, &thread.state, fas.Spec.Policy, fleet, gameServerNamespacedLister, c.counter.Counts(), &fasLog)
363+
desiredReplicas, scalingLimited, err := computeDesiredFleetSize(ctx, thread.state, fas.Spec.Policy, fleet, gameServerNamespacedLister, c.counter.Counts(), &fasLog)
364364

365365
// If the err is not nil and not an inactive schedule error (ignorable in this case), then record the event
366366
if err != nil {
@@ -498,7 +498,7 @@ func (c *Controller) addFasThread(fas *autoscalingv1.FleetAutoscaler, lock bool)
498498
thread := fasThread{
499499
cancel: cancel,
500500
generation: fas.Generation,
501-
state: fasState{},
501+
state: &fasState{},
502502
}
503503

504504
if lock {

pkg/fleetautoscalers/controller_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,9 +1178,9 @@ func TestControllerCleanFasThreads(t *testing.T) {
11781178

11791179
c.fasThreadMutex.Lock()
11801180
c.fasThreads = map[types.UID]fasThread{
1181-
"1": {func() {}, fasState{}, 1},
1182-
"2": {func() {}, fasState{}, 2},
1183-
fas.ObjectMeta.UID: {func() {}, fasState{}, 3},
1181+
"1": {func() {}, &fasState{}, 1},
1182+
"2": {func() {}, &fasState{}, 2},
1183+
fas.ObjectMeta.UID: {func() {}, &fasState{}, 3},
11841184
}
11851185
c.fasThreadMutex.Unlock()
11861186

pkg/fleetautoscalers/fleetautoscalers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ func applyWebhookPolicy(state *fasState, w *autoscalingv1.URLConfiguration, f *a
319319
return 0, false, err
320320
}
321321
defer func() {
322+
// Drain any unread body so the underlying connection can be reused by http.Transport.
323+
_, _ = io.Copy(io.Discard, res.Body)
322324
if cerr := res.Body.Close(); cerr != nil {
323325
if err != nil {
324326
err = errors.Wrap(err, cerr.Error())

0 commit comments

Comments
 (0)