Skip to content

Commit

Permalink
Move StateAllocationFilter to beta (googleforgames#2695)
Browse files Browse the repository at this point in the history
* fix failed tests due to missing GameServerState fields

* test StateAllocationFilter with FeatureGates inverted

* show and hide contents based on current semver

* make feature flags off to test stable

* add missing stable test

Co-authored-by: Mark Mandel <[email protected]>
  • Loading branch information
katsew and markmandel authored Aug 8, 2022
1 parent d741742 commit 23624d2
Show file tree
Hide file tree
Showing 12 changed files with 188 additions and 14 deletions.
2 changes: 1 addition & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ KIND_CONTAINER_NAME=$(KIND_PROFILE)-control-plane
# Game Server image to use while doing end-to-end tests
GS_TEST_IMAGE ?= gcr.io/agones-images/simple-game-server:0.13

ALPHA_FEATURE_GATES ?= "PlayerTracking=true&StateAllocationFilter=true&PlayerAllocationFilter=true&SDKGracefulTermination=true"
ALPHA_FEATURE_GATES ?= "PlayerTracking=true&PlayerAllocationFilter=true&SDKGracefulTermination=true"

# Build with Windows support
WITH_WINDOWS=1
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ steps:

- name: 'e2e-runner'
args:
- 'PlayerTracking=true&StateAllocationFilter=true&PlayerAllocationFilter=true&SDKGracefulTermination=true&CustomFasSyncInterval=false'
- 'PlayerTracking=true&StateAllocationFilter=false&PlayerAllocationFilter=true&SDKGracefulTermination=true&CustomFasSyncInterval=false'
- 'e2e-test-cluster'
- "${_REGISTRY}"
id: e2e-feature-gates
Expand Down
2 changes: 1 addition & 1 deletion examples/gameserverallocation-deprecated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ spec:
game: my-game
matchExpressions:
- {key: tier, operator: In, values: [cache]}
# [Stage:Alpha]
# [Stage:Beta]
# [FeatureFlag:StateAllocationFilter]
# Specifies which State is the filter to be used when attempting to retrieve a GameServer
# via Allocation. Defaults to "Ready". The only other option is "Allocated", which can be used in conjunction with
Expand Down
2 changes: 1 addition & 1 deletion examples/gameserverallocation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ spec:
game: my-game
matchExpressions:
- {key: tier, operator: In, values: [cache]}
# [Stage:Alpha]
# [Stage:Beta]
# [FeatureFlag:StateAllocationFilter]
# Specifies which State is the filter to be used when attempting to retrieve a GameServer
# via Allocation. Defaults to "Ready". The only other option is "Allocated", which can be used in conjunction with
Expand Down
35 changes: 33 additions & 2 deletions pkg/allocation/converters/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) {
},
},
{
name: "all fields are set",
name: "all fields are set",
features: fmt.Sprintf("%s=false&%s=false", runtime.FeaturePlayerAllocationFilter, runtime.FeatureStateAllocationFilter),
in: &pb.AllocationRequest{
Namespace: "ns",
MultiClusterSetting: &pb.MultiClusterSetting{
Expand Down Expand Up @@ -243,7 +244,8 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) {
},
},
{
name: "empty fields to GSA",
name: "empty fields to GSA",
features: fmt.Sprintf("%s=false&%s=false", runtime.FeaturePlayerAllocationFilter, runtime.FeatureStateAllocationFilter),
in: &pb.AllocationRequest{
Namespace: "",
MultiClusterSetting: &pb.MultiClusterSetting{},
Expand Down Expand Up @@ -290,6 +292,29 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) {
},
},
},
{
name: "empty fields to GSA with selectors fields",
features: fmt.Sprintf("%s=false&%s=false", runtime.FeaturePlayerAllocationFilter, runtime.FeatureStateAllocationFilter),
in: &pb.AllocationRequest{
Namespace: "",
MultiClusterSetting: &pb.MultiClusterSetting{},
GameServerSelectors: []*pb.GameServerSelector{{}},
Scheduling: pb.AllocationRequest_Distributed,
Metadata: &pb.MetaPatch{},
},
want: &allocationv1.GameServerAllocation{
ObjectMeta: metav1.ObjectMeta{
Namespace: "",
},
Spec: allocationv1.GameServerAllocationSpec{
MultiClusterSetting: allocationv1.MultiClusterSetting{
Enabled: false,
},
Selectors: []allocationv1.GameServerSelector{{}},
Scheduling: apis.Distributed,
},
},
},
{
name: "empty fields to GSA (StateAllocationFilter, PlayerAllocationFilter) with selectors fields",
features: fmt.Sprintf("%s=true&%s=true", runtime.FeaturePlayerAllocationFilter, runtime.FeatureStateAllocationFilter),
Expand Down Expand Up @@ -351,6 +376,9 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) {
MultiClusterSetting: allocationv1.MultiClusterSetting{
Enabled: false,
},
Required: allocationv1.GameServerSelector{
GameServerState: &ready,
},
Scheduling: apis.Distributed,
MetaPatch: allocationv1.MetaPatch{
Labels: map[string]string{
Expand Down Expand Up @@ -388,6 +416,9 @@ func TestConvertAllocationRequestToGameServerAllocation(t *testing.T) {
Enabled: false,
},
Scheduling: apis.Distributed,
Required: allocationv1.GameServerSelector{
GameServerState: &ready,
},
MetaPatch: allocationv1.MetaPatch{
Labels: map[string]string{
"a": "b",
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/allocation/v1/gameserverallocation.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ type GameServerAllocationSpec struct {
type GameServerSelector struct {
// See: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
metav1.LabelSelector
// [Stage:Alpha]
// [Stage:Beta]
// [FeatureFlag:StateAllocationFilter]
// +optional
// GameServerState specifies which State is the filter to be used when attempting to retrieve a GameServer
Expand Down
2 changes: 1 addition & 1 deletion pkg/util/runtime/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ var (
featureDefaults = map[Feature]bool{
FeatureExample: true,
FeaturePlayerTracking: false,
FeatureStateAllocationFilter: false,
FeatureStateAllocationFilter: true,
FeaturePlayerAllocationFilter: false,
FeatureCustomFasSyncInterval: true,
FeatureSDKGracefulTermination: false,
Expand Down
12 changes: 12 additions & 0 deletions site/content/en/docs/Guides/feature-stages.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ that can be found in the [Helm configuration]({{< ref "/docs/Installation/Instal

The current set of `alpha` and `beta` feature gates are:

{{% feature expiryVersion="1.26.0" %}}
| Feature Name | Gate | Default | Stage | Since |
|--------------|---------|---------|-------|-------|
| Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 |
Expand All @@ -32,6 +33,17 @@ The current set of `alpha` and `beta` feature gates are:
| [GameServer state filtering on GameServerAllocations](https://github.com/googleforgames/agones/issues/1239) | `StateAllocationFilter` | Disabled | `Alpha` | 1.14.0 |
| [GameServer player capacity filtering on GameServerAllocations](https://github.com/googleforgames/agones/issues/1239) | `PlayerAllocationFilter` | Disabled | `Alpha` | 1.14.0 |
| [Graceful Termination for GameServer SDK](https://github.com/googleforgames/agones/pull/2205) | `SDKGracefulTermination` | Disabled | `Alpha` | 1.18.0 |
{{% /feature %}}
{{% feature publishVersion="1.26.0" %}}
| Feature Name | Gate | Default | Stage | Since |
|--------------|---------|---------|-------|-------|
| Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 |
| [Player Tracking]({{< ref "/docs/Guides/player-tracking.md" >}}) | `PlayerTracking` | Disabled | `Alpha` | 1.6.0 |
| [Custom resync period for FleetAutoscaler](https://github.com/googleforgames/agones/issues/1955) | `CustomFasSyncInterval` | Enabled | `Beta` | 1.25.0 |
| [GameServer state filtering on GameServerAllocations](https://github.com/googleforgames/agones/issues/1239) | `StateAllocationFilter` | Enabled | `Beta` | 1.26.0 |
| [GameServer player capacity filtering on GameServerAllocations](https://github.com/googleforgames/agones/issues/1239) | `PlayerAllocationFilter` | Disabled | `Alpha` | 1.14.0 |
| [Graceful Termination for GameServer SDK](https://github.com/googleforgames/agones/pull/2205) | `SDKGracefulTermination` | Disabled | `Alpha` | 1.18.0 |
{{% /feature %}}

{{< alert title="Note" color="info" >}}
If you aren't sure if Feature Flags have been set correctly, have a look at the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ weight: 70
description: >
How to run multiple concurrent game sessions in a single GameServer process.
---

{{% feature expiryVersion="1.26.0" %}}
{{< alpha title="Allocation State Filter" gate="StateAllocationFilter" >}}
{{% /feature %}}
{{% feature publishVersion="1.26.0" %}}
{{< beta title="Allocation State Filter" gate="StateAllocationFilter" >}}
{{% /feature %}}

Depending on the setup and resource requirements of your game server process, sometimes it can be a more economical
use of resources to run multiple concurrent game sessions from within a single `GameServer` instance.
Expand Down
14 changes: 11 additions & 3 deletions site/content/en/docs/Integration Patterns/player-capacity.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@ description: >
Find a `GameServer` that has room for a specific number of players.
---

{{< alpha
title="Player Tracking, Allocation Player Filter, and Allocation State Filter"
gate="PlayerTracking,PlayerAllocationFilter,StateAllocationFilter" >}}
{{% feature expiryVersion="1.26.0" %}}
{{< alpha
title="Player Tracking, Allocation Player Filter, and Allocation State Filter"
gate="PlayerTracking,PlayerAllocationFilter,StateAllocationFilter" >}}
{{% /feature %}}
{{% feature publishVersion="1.26.0" %}}
{{< alpha
title="Player Tracking and Allocation Player Filter"
gate="PlayerTracking,PlayerAllocationFilter" >}}
{{< beta title="Allocation State Filter" gate="StateAllocationFilter" >}}
{{% /feature %}}

Using this approach, we are able to be able to make a request that is akin to: "Find me a `GameServer` that is already
allocated, with room for _n_ number of players, and if one is not available, allocate me a `Ready` `GameServer`".
Expand Down
4 changes: 2 additions & 2 deletions site/content/en/docs/Reference/agones_crd_api_reference.html
Original file line number Diff line number Diff line change
Expand Up @@ -1865,7 +1865,7 @@ <h3 id="allocation.agones.dev/v1.GameServerSelector">GameServerSelector
</td>
<td>
<em>(Optional)</em>
<p>[Stage:Alpha]
<p>[Stage:Beta]
[FeatureFlag:StateAllocationFilter]
GameServerState specifies which State is the filter to be used when attempting to retrieve a GameServer
via Allocation. Defaults to &ldquo;Ready&rdquo;. The only other option is &ldquo;Allocated&rdquo;, which can be used in conjunction with
Expand Down Expand Up @@ -5897,7 +5897,7 @@ <h3 id="allocation.agones.dev/v1.GameServerSelector">GameServerSelector
</td>
<td>
<em>(Optional)</em>
<p>[Stage:Alpha]
<p>[Stage:Beta]
[FeatureFlag:StateAllocationFilter]
GameServerState specifies which State is the filter to be used when attempting to retrieve a GameServer
via Allocation. Defaults to &ldquo;Ready&rdquo;. The only other option is &ldquo;Allocated&rdquo;, which can be used in conjunction with
Expand Down
119 changes: 119 additions & 0 deletions site/content/en/docs/Reference/gameserverallocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ A full `GameServerAllocation` specification is available below and in the
{{< ghlink href="/examples/gameserverallocation.yaml" >}}example folder{{< /ghlink >}} for reference:


{{% feature expiryVersion="1.26.0" %}}
{{< tabpane >}}
{{< tab header="selectors" lang="yaml" >}}
apiVersion: "allocation.agones.dev/v1"
Expand Down Expand Up @@ -126,6 +127,124 @@ spec:
map: garden22
{{< /tab >}}
{{< /tabpane >}}
{{% /feature %}}
{{% feature publishVersion="1.26.0" %}}
{{< tabpane >}}
{{< tab header="selectors" lang="yaml" >}}
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
# GameServer selector from which to choose GameServers from.
# Defaults to all GameServers.
# matchLabels, matchExpressions, gameServerState and player filters can be used for filtering.
# See: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more details on label selectors.
# An ordered list of GameServer label selectors.
# If the first selector is not matched, the selection attempts the second selector, and so on.
# This is useful for things like smoke testing of new game servers.
selectors:
- matchLabels:
agones.dev/fleet: green-fleet
# [Stage:Alpha]
# [FeatureFlag:PlayerAllocationFilter]
players:
minAvailable: 0
maxAvailable: 99
- matchLabels:
agones.dev/fleet: blue-fleet
- matchLabels:
game: my-game
matchExpressions:
- {key: tier, operator: In, values: [cache]}
# [Stage:Beta]
# [FeatureFlag:StateAllocationFilter]
# Specifies which State is the filter to be used when attempting to retrieve a GameServer
# via Allocation. Defaults to "Ready". The only other option is "Allocated", which can be used in conjunction with
# label/annotation/player selectors to retrieve an already Allocated GameServer.
gameServerState: Ready
# [Stage:Alpha]
# [FeatureFlag:PlayerAllocationFilter]
# Provides a filter on minimum and maximum values for player capacity when retrieving a GameServer
# through Allocation. Defaults to no limits.
players:
minAvailable: 0
maxAvailable: 99
# defines how GameServers are organised across the cluster.
# Options include:
# "Packed" (default) is aimed at dynamic Kubernetes clusters, such as cloud providers, wherein we want to bin pack
# resources
# "Distributed" is aimed at static Kubernetes clusters, wherein we want to distribute resources across the entire
# cluster
scheduling: Packed
# Optional custom metadata that is added to the game server at allocation
# You can use this to tell the server necessary session data
metadata:
labels:
mode: deathmatch
annotations:
map: garden22
{{< /tab >}}
{{< tab header="required & preferred (deprecated)" lang="yaml" >}}
apiVersion: "allocation.agones.dev/v1"
kind: GameServerAllocation
spec:
# Deprecated, use field selectors instead.
# GameServer selector from which to choose GameServers from.
# Defaults to all GameServers.
# matchLabels, matchExpressions, gameServerState and player filters can be used for filtering.
# See: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ for more details on label selectors.
# Deprecated, use field selectors instead.
required:
matchLabels:
game: my-game
matchExpressions:
- {key: tier, operator: In, values: [cache]}
# [Stage:Beta]
# [FeatureFlag:StateAllocationFilter]
# Specifies which State is the filter to be used when attempting to retrieve a GameServer
# via Allocation. Defaults to "Ready". The only other option is "Allocated", which can be used in conjunction with
# label/annotation/player selectors to retrieve an already Allocated GameServer.
gameServerState: Ready
# [Stage:Alpha]
# [FeatureFlag:PlayerAllocationFilter]
# Provides a filter on minimum and maximum values for player capacity when retrieving a GameServer
# through Allocation. Defaults to no limits.
players:
minAvailable: 0
maxAvailable: 99
# Deprecated, use field selectors instead.
# An ordered list of preferred GameServer label selectors
# that are optional to be fulfilled, but will be searched before the `required` selector.
# If the first selector is not matched, the selection attempts the second selector, and so on.
# If any of the preferred selectors are matched, the required selector is not considered.
# This is useful for things like smoke testing of new game servers.
# This also support matchExpressions, gameServerState and player filters.
preferred:
- matchLabels:
agones.dev/fleet: green-fleet
# [Stage:Alpha]
# [FeatureFlag:PlayerAllocationFilter]
players:
minAvailable: 0
maxAvailable: 99
- matchLabels:
agones.dev/fleet: blue-fleet
# defines how GameServers are organised across the cluster.
# Options include:
# "Packed" (default) is aimed at dynamic Kubernetes clusters, such as cloud providers, wherein we want to bin pack
# resources
# "Distributed" is aimed at static Kubernetes clusters, wherein we want to distribute resources across the entire
# cluster
scheduling: Packed
# Optional custom metadata that is added to the game server at allocation
# You can use this to tell the server necessary session data
metadata:
labels:
mode: deathmatch
annotations:
map: garden22
{{< /tab >}}
{{< /tabpane >}}
{{% /feature %}}

The `spec` field is the actual `GameServerAllocation` specification, and it is composed as follows:

Expand Down

0 comments on commit 23624d2

Please sign in to comment.