Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better track ConnectedPlayers #35

Closed
dgkanatsios opened this issue Oct 17, 2021 · 2 comments · Fixed by #48
Closed

Better track ConnectedPlayers #35

dgkanatsios opened this issue Oct 17, 2021 · 2 comments · Fixed by #48
Assignees
Labels
design enhancement New feature or request

Comments

@dgkanatsios
Copy link
Collaborator

dgkanatsios commented Oct 17, 2021

Currently, when a user allocates a GameServer, they pass a string array of Player IDs. This is persisted in the InitialPlayers string slice on the GameServer.Status field and passed in the GameServer via GSDK Heartbeat response. However, GameServer can call UpdateConnectedPlayers on the GSDK to update the Connected Players list. Currently, the sidecar gets informed of the change but does nothing. It would be helpful if the sidecar tracked this change and persisted it somewhere, since on some GameServers you may have users jumping in and out during the game session. Some options to solve this problem:

  • rename the InitialPlayers on the GameServerStatus to ConnectedPlayers and keep everything there. This list can be big sometimes though (we've seen games with 64 players). I don't think we'll have storage issues (I doubt that the CRD instance on etcd will grow more than 1.5 MB - link) but I'm not sure about perf issues on transferring CRD instance data from the K8s API server to the controller and vice versa.
  • keep the InitialPlayers and store subsequent players on a ConfigMap, unique per GameServer. GameServer has a finalizer so we could do the cleanup of the ConfigMap there, when the GameServer gets deleted.
  • remove the InitialPlayers on the CRD and just keep a ConnectedPlayers string slice on a ConfigMap. This will be a breaking change but we consider it acceptable at this stage of the project.

Thoughts @khaines?

@dgkanatsios dgkanatsios added enhancement New feature or request design labels Oct 17, 2021
@dgkanatsios
Copy link
Collaborator Author

After some thinking, I believe it would be better if we totally remove the InitialPlayers array from the GameServer CRD. Some games might have a lot of players and this will make the CRD object big, which may have performance implications as it's transferred/marshalled across the wire.
We'd need to store these two state items in etcd, to have a similar behavior with PlayFab MPS:

  • InitialPlayers []string: this can be fetched by the game server process (via GSDK) and do a validation of the players that will join the game session upon its creation
  • ConnectedPlayersCount int: this will be updated (PATCHed) by the sidecar when there is a change in the count of connected players, which is updated by the UpdateConnectedPlayers GSDK call. Whereas the sidecar will hold the actual players IDs/usernames, we need to store only the Count/Length of it. This information will be useful to a potential future GameServer autoscaler which will modify the standingBy settings of the GameServerBuild depending on the actual connected player population.
    One question arises, on how to store this information. We can always use a ConfigMap but we can also use a new CRD (called GameServerData). There is no need for a controller for this CRD. The main benefit of using a CRD over a ConfigMap is the auto marshalling/unmarshalling of data plus the fact that it will be strongly typed. The downside is that if we want to introduce a new field, we'd have to provide a new version of the CRD.

@dgkanatsios
Copy link
Collaborator Author

dgkanatsios commented Oct 27, 2021

We're gonna go with a custom CRD for the time being, called GameServerDetail. Initial design:

  • remove InitialPlayers from GameServer CRD
  • create the CRD with .Spec of []string InitialPlayers and bool ConnectedPlayersCount
  • when the GameServer is allocated, the allocation API service creates the GameServerDetail CRD instance that has the same name as the GameServer CRD instance, with InitialPlayers and ConnectedPlayersCount
  • when the GameServer is allocated, the sidecar watch fetches InitialPlayers from the GameServerDetail CRD, passes them to the game server process via the GSDK heartbeat
  • when user calls GSDK.UpdateConnectedPlayers(), the sidecar will PATCH the CRD instance with the new value for ConnectedPlayersCount

This was referenced Oct 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants