fix(multiplayer): persist arena identity on allocations

This commit is contained in:
Josh Creek
2026-09-01 21:16:42 +01:00
parent d4bde67e0f
commit 2ff348adf0
8 changed files with 27 additions and 15 deletions
+9 -9
View File
@@ -31,11 +31,11 @@ WHERE server_id = (
RETURNING server_id`
const InsertAllocationSQL = `INSERT INTO allocations
(allocation_id, match_id, server_id, region, build, protocol_version, transport, request_digest, state, allocated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'ALLOCATED', $9)`
(allocation_id, match_id, server_id, region, build, protocol_version, arena_path, transport, request_digest, state, allocated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, 'ALLOCATED', $10)`
const SelectAllocationSQL = `SELECT allocation_id, match_id, server_id, region, build,
protocol_version, transport, allocated_at, request_digest
protocol_version, arena_path, transport, allocated_at, request_digest
FROM allocations WHERE allocation_id = $1`
const ProviderServerClaimSQL = `UPDATE game_servers SET state = 'ALLOCATED', updated_at = $6
@@ -63,7 +63,7 @@ func ClaimAllocation(ctx context.Context, db *sql.DB, request domain.AllocationR
err := RunSerializable(ctx, db, DefaultSerializableAttempts, func(ctx context.Context, tx *sql.Tx) error {
var prior domain.Allocation
var priorDigest []byte
err := tx.QueryRowContext(ctx, SelectAllocationSQL, request.AllocationID).Scan(&prior.AllocationID, &prior.MatchID, &prior.ServerID, &prior.Region, &prior.Build, &prior.Protocol, &prior.Transport, &prior.AllocatedAt, &priorDigest)
err := tx.QueryRowContext(ctx, SelectAllocationSQL, request.AllocationID).Scan(&prior.AllocationID, &prior.MatchID, &prior.ServerID, &prior.Region, &prior.Build, &prior.Protocol, &prior.ArenaPath, &prior.Transport, &prior.AllocatedAt, &priorDigest)
if err == nil {
if !bytes.Equal(priorDigest, digest[:]) {
return domain.ErrConflict
@@ -85,8 +85,8 @@ func ClaimAllocation(ctx context.Context, db *sql.DB, request domain.AllocationR
}
return err
}
allocation = domain.Allocation{AllocationID: request.AllocationID, MatchID: request.MatchID, ServerID: serverID, Region: request.Region, Build: request.Build, Protocol: request.Protocol, Transport: request.Transport, State: domain.ServerAllocated, AllocatedAt: now}
_, err = tx.ExecContext(ctx, InsertAllocationSQL, request.AllocationID, request.MatchID, serverID, request.Region, request.Build, request.Protocol, request.Transport, digest[:], now)
allocation = domain.Allocation{AllocationID: request.AllocationID, MatchID: request.MatchID, ServerID: serverID, Region: request.Region, Build: request.Build, Protocol: request.Protocol, ArenaPath: request.ArenaPath, Transport: request.Transport, State: domain.ServerAllocated, AllocatedAt: now}
_, err = tx.ExecContext(ctx, InsertAllocationSQL, request.AllocationID, request.MatchID, serverID, request.Region, request.Build, request.Protocol, request.ArenaPath, request.Transport, digest[:], now)
return err
})
return allocation, err
@@ -97,7 +97,7 @@ func ClaimAllocation(ctx context.Context, db *sql.DB, request domain.AllocationR
// Agones has already selected the server; no client-facing assignment may use
// the result until this exact tuple is durably recorded.
func RecordProviderAllocation(ctx context.Context, db *sql.DB, allocation domain.Allocation, now time.Time) (domain.Allocation, error) {
request := domain.AllocationRequest{AllocationID: allocation.AllocationID, MatchID: allocation.MatchID, Region: allocation.Region, Build: allocation.Build, Protocol: allocation.Protocol, Transport: allocation.Transport}
request := domain.AllocationRequest{AllocationID: allocation.AllocationID, MatchID: allocation.MatchID, Region: allocation.Region, Build: allocation.Build, Protocol: allocation.Protocol, ArenaPath: allocation.ArenaPath, Transport: allocation.Transport}
if !validAllocationInput(db, request, now) || allocation.State != domain.ServerAllocated || allocation.ServerID == "" {
return domain.Allocation{}, domain.ErrAllocationInput
}
@@ -106,7 +106,7 @@ func RecordProviderAllocation(ctx context.Context, db *sql.DB, allocation domain
err := RunSerializable(ctx, db, DefaultSerializableAttempts, func(ctx context.Context, tx *sql.Tx) error {
var prior domain.Allocation
var priorDigest []byte
err := tx.QueryRowContext(ctx, SelectAllocationSQL, allocation.AllocationID).Scan(&prior.AllocationID, &prior.MatchID, &prior.ServerID, &prior.Region, &prior.Build, &prior.Protocol, &prior.Transport, &prior.AllocatedAt, &priorDigest)
err := tx.QueryRowContext(ctx, SelectAllocationSQL, allocation.AllocationID).Scan(&prior.AllocationID, &prior.MatchID, &prior.ServerID, &prior.Region, &prior.Build, &prior.Protocol, &prior.ArenaPath, &prior.Transport, &prior.AllocatedAt, &priorDigest)
if err == nil {
if !bytes.Equal(priorDigest, digest[:]) || prior.ServerID != allocation.ServerID {
return domain.ErrConflict
@@ -133,7 +133,7 @@ func RecordProviderAllocation(ctx context.Context, db *sql.DB, allocation domain
}
recorded = allocation
recorded.AllocatedAt = now
_, err = tx.ExecContext(ctx, InsertAllocationSQL, allocation.AllocationID, allocation.MatchID, serverID, allocation.Region, allocation.Build, allocation.Protocol, allocation.Transport, digest[:], now)
_, err = tx.ExecContext(ctx, InsertAllocationSQL, allocation.AllocationID, allocation.MatchID, serverID, allocation.Region, allocation.Build, allocation.Protocol, allocation.ArenaPath, allocation.Transport, digest[:], now)
return err
})
return recorded, err