mirror of
https://github.com/jcreek/CosmicClash.git
synced 2026-09-13 08:52:03 +00:00
feat(multiplayer): propagate match ID to an already-allocated pod via annotations
Investigated the Fleet-manifest wiring task flagged last commit and found a deeper, previously-undesigned gap: Kubernetes env vars are fixed at pod creation, but Agones allocates a match to an already- running Ready pod well after it starts -- so there was no channel at all for match-specific data (match ID) to reach that pod's processes. Close it using the Agones GameServerAllocation API's documented spec.metadata.annotations field, which Agones applies to the allocated GameServer's own object_meta on success: server/agones.Client.Allocate now requests cosmic-clash.io/match-id and cosmic-clash.io/allocation-id annotations, and the supervisor reads them back from the same /gameserver SDK call it already makes for the assigned port/address (GameServer.ObjectMeta.Annotations), falling back to them for its own control-plane registration only when MatchID isn't explicitly configured -- an explicit value always wins, and a match ID resolvable from neither source fails Start() closed before any HTTP call. The exact object_meta vs objectMeta JSON key from a live Agones SDK sidecar is not independently verified from this sandbox; documented inline, and the fallback degrades safely (empty annotations map, same as before this change) if it turns out to be wrong. Covered by two new tests: the annotation actually flowing through to the registration body, and fail-closed with neither config nor annotation supplying a match ID (registerCalled stays false, not just that Start() errors).
This commit is contained in:
@@ -37,6 +37,18 @@ type allocationRequest struct {
|
||||
Selectors []struct {
|
||||
MatchLabels map[string]string `json:"matchLabels"`
|
||||
} `json:"selectors"`
|
||||
// Metadata.Annotations is applied to the allocated GameServer's own
|
||||
// object_meta by Agones on successful allocation (a documented part
|
||||
// of the GameServerAllocation spec, independent of the Selectors
|
||||
// used to find capacity). This is the only way match-specific data
|
||||
// reaches an already-Ready pod after allocation: Kubernetes env vars
|
||||
// are fixed at pod creation, long before Agones assigns a match to
|
||||
// that pod, so there is no other channel for it. The allocated
|
||||
// process reads these back via the SDK's own GameServer call
|
||||
// (server/supervisor's existing /gameserver request).
|
||||
Metadata struct {
|
||||
Annotations map[string]string `json:"annotations"`
|
||||
} `json:"metadata"`
|
||||
} `json:"spec"`
|
||||
}
|
||||
|
||||
@@ -139,6 +151,10 @@ func (c Client) Allocate(ctx context.Context, request domain.AllocationRequest,
|
||||
body.Spec.Selectors = []struct {
|
||||
MatchLabels map[string]string `json:"matchLabels"`
|
||||
}{{MatchLabels: cloneLabels(labels)}}
|
||||
body.Spec.Metadata.Annotations = map[string]string{
|
||||
"cosmic-clash.io/match-id": request.MatchID,
|
||||
"cosmic-clash.io/allocation-id": request.AllocationID,
|
||||
}
|
||||
encoded, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
return AllocatedServer{}, err
|
||||
|
||||
@@ -28,6 +28,9 @@ func TestAllocateBuildsStrictGameServerAllocationAndEndpoint(t *testing.T) {
|
||||
if body.APIVersion != "allocation.agones.dev/v1" || body.Kind != "GameServerAllocation" || len(body.Spec.Selectors) != 1 || body.Spec.Selectors[0].MatchLabels["cosmic-clash/region"] != "EU" {
|
||||
t.Fatalf("body=%+v", body)
|
||||
}
|
||||
if body.Spec.Metadata.Annotations["cosmic-clash.io/match-id"] != "match-1" || body.Spec.Metadata.Annotations["cosmic-clash.io/allocation-id"] != "allocation-1" {
|
||||
t.Fatalf("allocation did not request match/allocation ID annotations on the GameServer: %+v", body.Spec.Metadata.Annotations)
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"status":{"state":"Allocated","gameServerName":"gs-a","address":"2001:db8::1","ports":[{"name":"default","port":7777}]}}`))
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user