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

Player Tracking for each GameServer #1033

Closed
markmandel opened this issue Sep 4, 2019 · 26 comments
Closed

Player Tracking for each GameServer #1033

markmandel opened this issue Sep 4, 2019 · 26 comments
Assignees
Labels
area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc kind/design Proposal discussing new features / fixes and how they should be implemented kind/feature New features for Agones
Milestone

Comments

@markmandel
Copy link
Member

markmandel commented Sep 4, 2019

Is your feature request related to a problem? Please describe.
It would be very useful to track player connection and disconnection against a specific GameServer.

This would allow us to do several things:

  • Track if a GameServer is full or not (we should also track GameServer capacity as well)
  • Be able to trace and debug a player lifecycle from matchmaker to gameserver connection (we should track an id or token on connection)
  • Autoscale Fleets based on how full gameservers are (useful for persistent worlds)

Describe the solution you'd like
(Full design TBD)

  • Need a way to specify the capacity of a GameServer, at creation time, but also editable from the SDK at runtime
  • SDK methods to track a player connection, and player disconnection with an id/player token
  • GameServer CRD Events for player connections and disconnections
  • GameServer CRD Status values that track player counts and capacity. Maybe should also have a list of current connected players?
  • May want to add some labels to allow for searching for full/empty/partially full game servers through the k8s api

Describe alternatives you've considered
Have a separate system for player tracking - but based on feedback, this is a feature that almost all users should find useful, so it feels like part of Agones, and also allows some useful functionality down the road -- such as autoscaling by player count, or automating backfill operations by searching for non-full game servers.

Additional context
I do have concerns that we are adding more API QPS with this, so we should track performance with these changes.

@markmandel markmandel added kind/feature New features for Agones kind/design Proposal discussing new features / fixes and how they should be implemented area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc labels Sep 4, 2019
@cyriltovena
Copy link
Collaborator

cyriltovena commented Sep 15, 2019

I also do have a concern for etcd, it could potentially be a lot depending on the design.

A Kubernetes event each time a player join ?

@markmandel
Copy link
Member Author

Yeah agreed - was chatting with some people the other day, talking through this,

The basic idea we ended up thinking, which I think would work better long term (there are some implementation design decisions to work out too) are:

  • Only keep the player count and capacity on the GameServer CRD status value.
  • The SDK could be smart, and only sync the player count once every second (or configurable interval?), to avoid overloading the system when huge numbers come in. Backfill based on player counts will have race conditions anyway, so games will need to deal with this regardless.
  • The an event might just be the update to the player count, not each player, on the same interval as above.

To track players - have a CRD configurable webhook that has player data sent to it on connection / disconnection. Something like the gameserver name, connect/disconnect and the token that is passed through. Then we can build a separate system(s) for storing and tracking connections, and/or respond to events as needed as well.

In theory the sidecar would need to send the webhook request (I think),, but that's doable (and an implementation detail).

This requires a full write up, but I think it sounds like a reasonable approach at first pass. WDYT?

@markmandel
Copy link
Member Author

markmandel commented Jan 7, 2020

Design ideas

The following is implementation design for both the configuration, status and game server SDK.

Feedback is much appreciated.

Configuration & Status

apiVersion: "agones.dev/v1"
kind: GameServer
metadata:
  generateName: "simple-udp-"
spec:
  # new configuration
  alpha:
    players:
      initialCapacity: 10 # sets the initial player capacity. Defaults to 0.
      webhook: # http(s) webhook to send player dis/connection events
        service:
          name: player-tracking-service
          namespace: default
          path: player
  ports:
  - name: default
    portPolicy: Dynamic
    containerPort: 7654
  template:
    spec:
      containers:
      - name: simple-udp
        image: gcr.io/agones-images/udp-server:0.17
status:
  alpha:
    # tracks players
    players:
      count: 6 # current number of players. Only updated one per second, so eventually consistent.
      capacity: 10 # current capacity. Set by "initialCapacity" and can be changed by the SDK
  • spec.alpha.players.initialCapacity - the initial player capacity as listed in the status value status.players.capacity
  • spec.alpha.players.webhook - a webhook configuration that is called whenever a player connects or disconnects. This sort of data seems ill-suited to CRDs, so Agones never stores these values, it’s the responsibility of another system to track this information as required.
    The webhook POSTs a JSON payload with the following details:
    • GameServer name
    • PlayerID (provided through the SDK)
    • Event: “connect” or “disconnect”
  • status.alpha.players.count - The current number of players in the system. This information will be eventually consistent as it is only updated once per second to avoid overloading the system. Since player count race conditions are inevitable, there should always be extra checking of player counts on player connection to a game server.
  • status.alpha.players.capacity - The current player capacity of this gameserver. Initially set by the initialCapacity value, but also able to be changed at runtime by the Game Server SDK.

SDK Functionality

SDK.Alpha.PlayerConnect(playerID)

This increases the SDK’s stored player count by one, and passes the playerID to the system such that it can fire the webhook with a connection event to any configured receivers.

status.alpha.players.count is then set to update to the current player count a second from now, unless there is already an update pending.

Will throw an error if the player count is equal to or greater than the capacity.

SDK.Alpha.PlayerDisconnect(playerID) : bool

Decreases the SDK’s stored player count by one, and passes the playerID to the system such that it can fire the webhook with a disconnection event to any configured receivers.

status.alpha.players.count is then set to update to the current player count a second from now, unless there is already an update pending.

Does nothing, and returns false if the playerID was not previously added. Returns true otherwise.

SDK.Alpha.SetPlayerCapacity(int capacity)

Update the status.alpha.capacity value with a new capacity.

SDK.Alpha.GetPlayerCapacity() : int

Retrieves the current capacity. This is always accurate, even if the value hasn’t been updated to the GameServer status yet.

SDK.Alpha.GetPlayerCount() : int

Retrieves the current player count. This is always accurate, even if the value hasn’t been updated to the GameServer status yet.

@aLekSer
Copy link
Collaborator

aLekSer commented Jan 22, 2020

I have some questions regarding PlayerConnect:

SDK.Alpha.PlayerConnect(playerID)
This increases the SDK’s stored player count by one, and passes the playerID to the system such that it can fire the webhook with a connection event to any configured receivers.

Should we wait for webhook response that this player is able to connect? Who would be judging the player if he is able or not able to connect to the session?

Would playerID be stored on GS SDK side or separately?

Then we can build a separate system(s) for storing and tracking connections, and/or respond to events as needed as well.

@cloudrobx
Copy link

cloudrobx commented Jan 22, 2020 via email

@markmandel
Copy link
Member Author

@aLekSer good questions!

Should we wait for webhook response that this player is able to connect?

Personally, I don't think so. This could potentially make things very slow in the game server binary. I feel like this should be an async operation that happens behind the scenes.

Who would be judging the player if he is able or not able to connect to the session?

This is up to the game server binary to make this decision. So it's game / transport layer specific.

Would playerID be stored on GS SDK side or separately?

In this design, we don't store the playerID at all (except transiently in memory as it gets passed to the system that sends the webhook request). playerID management is up to the game author to track and manage. This is the main impetus for the webhook, to make this easier.

While it could be useful to store playerIDs in a CRD, it seems like a performance concern for etcd. Maybe something to explore down the line if we find we have bandwidth in etcd performance.

@cloudrobx

Could this metric be utilized for autoscaling? I'm wondering for the relay
server use case, in which multiple relay server processes would run inside
a single GameServer container and we need a test for "fullness" for
autoscaling up and down.

Like this? #1034 😄 would that work for what you were thinking?

@cloudrobx
Copy link

cloudrobx commented Jan 24, 2020 via email

@markmandel
Copy link
Member Author

Yeah something like that looks pretty good. For placement purposes is
there an easy way to pull the most (or least) full game server by player
count, other than iterating through all the game servers in the cluster?

See: #1239 for current initial thoughts.

@cloudrobx
Copy link

cloudrobx commented Jan 24, 2020 via email

@markmandel
Copy link
Member Author

For relays / high density would probably also want the ability to find the
most empty or most full server as well. Since you're essentially adding
another layer of bin-packing.

This sounds like the current "Distributed" vs "Packed" strategies we already have in place. Also probably a topic to discuss more on #1239 rather than here, since this ticket isn't covering allocation - just player count tracking.

@markmandel
Copy link
Member Author

Made a small tweak to SDK. Renamed GetCapacity and SetCapacity to GetPlayerCapacity and SetPlayerCapacity - just to be clearer.

markmandel added a commit to markmandel/agones that referenced this issue Feb 1, 2020
Implementation of the alpha functions for player tracking in the proto
definition.

This includes a interface and non-working stub for the Go gRPC clients
as well.

Copyright notices where updated to 2020 on the other languages as they
were regenerated during the process.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 5, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 5, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 5, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 5, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 7, 2020
Implementation of the alpha functions for player tracking in the proto
definition.

This includes a interface and non-working stub for the Go gRPC clients
as well.

Copyright notices where updated to 2020 on the other languages as they
were regenerated during the process.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 8, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 8, 2020
Implementation of the alpha functions for player tracking in the proto
definition.

This includes a interface and non-working stub for the Go gRPC clients
as well.

Copyright notices where updated to 2020 on the other languages as they
were regenerated during the process.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 8, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
markmandel added a commit to markmandel/agones that referenced this issue Feb 11, 2020
Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033
@Reousa
Copy link
Contributor

Reousa commented May 29, 2020

Hey Mark! Thanks for the heads up, would be great to be able to contribute again! :)

Gave the issue a read, I see these have already been updated to the relevant proto files, so all that's needed is the relevant language implementation, yeah?

If my understanding is correct, consider it done (hopefully in a timely manner)! 👌

@markmandel
Copy link
Member Author

That's a good point - you will need to edit the gen.sh scripts such that they generate the code for the alpha.proto, and then yes -- implement the SDK over the top 👍

Thanks!

@steven-supersolid
Copy link
Collaborator

Working on Node.js now

This was referenced Jul 21, 2020
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Implementation of the alpha functions for player tracking in the proto
definition.

This includes a interface and non-working stub for the Go gRPC clients
as well.

Copyright notices where updated to 2020 on the other languages as they
were regenerated during the process.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
* CRD implementation of alpha player tracking

Update to CRD implementation, and pkg/api/gameserver.go and default
value implementation.

Work on googleforgames#1033

* Including feature flag locking.

Required to allow tests to pass with race checking enabled.
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
This PR doesn't complete this functionality, but was enough to warrant
review.

It does two things:
1. The refactoring to move alpha and beta SDK Server implementations
into the same file as the main SDK Server, as being able to reuse the
current logic made sense on review.
2. Initial Implementation of SDK GetPlayerCapacity & SetPlayerCapacity
methods with unit tests. E2E tests can be implemented once googleforgames#1397 is
resolved.

Next steps will be to implement the local SDK functionality, and
conformance tests for Go for these two functions.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Local SDK implementations of SetPlayerCapacity and GetPlayerCapacity,
including conformance tests for the Go SDK.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
This updates the GameServer CRD based on the
[updated design](googleforgames#1033 (comment))
for Player Tracking.
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
This includes changes to make PlayerID consistent in casing.

Code generation will come in the next PR to make things easier to
review.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
* Regenerate gRPC code.

* Code Gen and Stubs for updated Player Tracking

This PR is an update to the code generated from the Player Tracking
proto updates, and the accompanying method stubs so that everything
compiles and passes tests.

Feature implementation work to come next!

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Looks like I missed this on initial implementation.

Work on googleforgames#1033

Co-authored-by: Alexander Apalikov <[email protected]>
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
When converting from CRD->gRPC model, add the Player Tracking IDs

Work on googleforgames#1033

Co-authored-by: Alexander Apalikov <[email protected]>
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Implementation and unit tests for Player Tracking for the local sdk
server.

Conformance tests will come after this.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Implementation of the SDK gRPC Server, with accompanying unit tests.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
This PR is only the structure to store aggregate values for player
tracking data across Fleets and GameServerSets.

Later PRs will implement the logic.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Fix on a small capitalisation issue on JSON output of the GameServer CRD
changes.

Work on googleforgames#1033

Co-authored-by: pooneh-m <[email protected]>
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Cleanup proto IDs field to conform to naming convention.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Fix this up so it also conforms to naming conventions.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Reference for the general Player Tracking SDK API.

This included some slight reorganising, to make it less cluttered as we
add more functionality.

To come, is a full player tracking guide, and updates to the GameServer
reference.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Implementation of aggregation of Player Tracking values at the Fleet and
GameServerSet levels.

Includes both unit and e2e tests.

Work on googleforgames#1033

Co-authored-by: Robert Bailey <[email protected]>
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Includes the guide for player tracking, explaining how the SDK commands
can be used for player user journeys.

Included is also updates to the GameServer references.

Also included a small fix in the comments wherein we were still
referencing the webhook from the previous design.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Reference for player tracking API for the REST interface for the SDK.

Also regrouped as how we now have it in the Client SDK guide.

Work on googleforgames#1033
ilkercelikyilmaz pushed a commit to ilkercelikyilmaz/agones that referenced this issue Oct 23, 2020
Includes the guide for player tracking, explaining how the SDK commands
can be used for player user journeys.

Included is also updates to the GameServer references.

Also included a small fix in the comments wherein we were still
referencing the webhook from the previous design.

Work on googleforgames#1033
@markmandel
Copy link
Member Author

I'm going to suggest we close this ticket, since this has been released to alpha, and there is (mostly?) supported in the SDKs - and I think we can then track each of those as seperate tickets as needed.

Also #1677 is going to break all the things (will likely aim to tackle in the next release), so we can track the ongoing work there as well.

Sound good?

@roberthbailey
Copy link
Member

Closing as per the last comment (1.5 years ago).

@Kalaiselvi84 Kalaiselvi84 added this to the 1.30.0 milestone Feb 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/user-experience Pertaining to developers trying to use Agones, e.g. SDK, installation, etc kind/design Proposal discussing new features / fixes and how they should be implemented kind/feature New features for Agones
Projects
None yet
Development

No branches or pull requests

9 participants