Skip to content

fix: duplicate GameServerSets not being cleaned up under a Fleet#4469

Open
mnthe wants to merge 1 commit intoagones-dev:mainfrom
mnthe:fix/duplicate-gameserverset-cleanup
Open

fix: duplicate GameServerSets not being cleaned up under a Fleet#4469
mnthe wants to merge 1 commit intoagones-dev:mainfrom
mnthe:fix/duplicate-gameserverset-cleanup

Conversation

@mnthe
Copy link

@mnthe mnthe commented Mar 12, 2026

What type of PR is this?

/kind bug

What this PR does / Why we need it:

Fixes a bug in filterGameServerSetByActive() where duplicate GameServerSets sharing the same template as the Fleet are silently dropped — placed in neither the active nor the rest slice.

When multiple GameServerSets match the Fleet's template, the current code overwrites the active variable on each match (last-write-wins). Earlier matches are lost entirely: they don't go into rest, so applyDeploymentStrategy() and deleteEmptyGameServerSets() never touch them.

This causes two problems:

  1. Orphaned GameServerSets that are never scaled down or deleted.
  2. All duplicates converge to the Fleet's desired replica count,
    • because the Kubernetes informer store iterates a Go map with non-deterministic ordering — each syncFleet() can pick a different GSS as "active" and update its Spec.Replicas.

Screenshot — 3 duplicate GameServerSets under a single Fleet, all with the same Desired value:

무제

The fix keeps the oldest GameServerSet (by CreationTimestamp) as active and places any duplicates into the rest slice, where the existing deployment strategy logic naturally scales them down and deletes them.

Which issue(s) this PR fixes:

Closes #4468

Special notes for your reviewer:

  • Root cause is in filterGameServerSetByActive() (pkg/fleets/controller.go), which has had last-write-wins behavior since its initial implementation and has never been modified.
  • Added TestControllerFilterGameServerSetByActiveDuplicates covering:
    • 3 duplicate-template GSS → oldest selected as active, others in rest
    • Non-deterministic list ordering → same deterministic result
    • Mix of matching and non-matching templates
  • All existing tests pass (make test-go).
  • Minimal change: 17 lines added to the function, 55 lines of new tests.

Does this PR introduce a user-facing change?

Fixed a bug where duplicate GameServerSets with the same template could
accumulate under a Fleet without being cleaned up, causing replicas to
multiply beyond the desired count.

When multiple GameServerSets with the same template exist under a
single Fleet (caused by informer cache lag during creation),
filterGameServerSetByActive() used last-write-wins semantics: only
the last matching GameServerSet in the list was kept as active, while
earlier matches were silently dropped — placed in neither the active
nor the rest slice.

This caused two problems:
1. Duplicate GameServerSets were never scaled down or deleted, since
   they were invisible to applyDeploymentStrategy() and
   deleteEmptyGameServerSets().
2. Because the Kubernetes informer store iterates over a Go map with
   non-deterministic ordering, each syncFleet() call could pick a
   different GameServerSet as "active", causing all duplicates to
   eventually have their Spec.Replicas updated to the Fleet's desired
   count — resulting in N times the expected number of GameServers.

Fix: when multiple GameServerSets match the Fleet template, keep the
oldest by CreationTimestamp as active and place the rest in the rest
slice for normal scale-down and cleanup.
@github-actions github-actions bot added kind/bug These are bugs. size/S labels Mar 12, 2026
@google-cla
Copy link

google-cla bot commented Mar 12, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@mnthe mnthe changed the title Fix duplicate GameServerSets not being cleaned up under a Fleet fix: duplicate GameServerSets not being cleaned up under a Fleet Mar 12, 2026
@mnthe mnthe marked this pull request as ready for review March 12, 2026 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug These are bugs. size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fleet controller does not clean up duplicate GameServerSets with matching spec

1 participant