fix(multiplayer): avoid quota double charge on recovery

This commit is contained in:
Josh Creek
2026-09-01 21:39:18 +01:00
parent eb3b685af0
commit d3a457d8d0
3 changed files with 26 additions and 11 deletions
+21 -3
View File
@@ -97,7 +97,7 @@ func TestServiceConsumesSharedQuotaBeforeFreshProviderCall(t *testing.T) {
}
}
func TestServiceConsumesSharedQuotaOnceWhenReconcilingProviderResult(t *testing.T) {
func TestServiceDoesNotConsumeSharedQuotaWhenReconcilingProviderResult(t *testing.T) {
quota := &quotaSpy{}
durable := &durableSpy{}
service := Service{Durable: durable, Quota: quota, Now: func() time.Time { return time.Unix(1000, 0) }}
@@ -105,8 +105,26 @@ func TestServiceConsumesSharedQuotaOnceWhenReconcilingProviderResult(t *testing.
if _, err := service.RecordProviderAllocation(context.Background(), result, time.Unix(1000, 0)); err != nil {
t.Fatalf("reconciliation failed: %v", err)
}
if quota.calls != 1 || durable.calls != 1 {
t.Fatalf("quota/durable calls = %d/%d, want 1/1", quota.calls, durable.calls)
if quota.calls != 0 || durable.calls != 1 {
t.Fatalf("quota/durable calls = %d/%d, want 0/1", quota.calls, durable.calls)
}
}
func TestServiceDoesNotDoubleChargeQuotaAfterProviderResultRecovery(t *testing.T) {
quota := &quotaSpy{}
durable := &durableSpy{err: errors.New("recording unavailable")}
provider := &providerSpy{result: agones.AllocatedServer{Allocation: domain.Allocation{AllocationID: "a", MatchID: "m", Region: "EU", State: domain.ServerAllocated}, Endpoint: "127.0.0.1:7777"}}
service := Service{Provider: provider, Durable: durable, Quota: quota, Now: func() time.Time { return time.Unix(1000, 0) }}
request := domain.AllocationRequest{AllocationID: "a", MatchID: "m", Region: "EU", Build: "b", Protocol: 1, Transport: "enet"}
if _, err := service.Allocate(context.Background(), request, nil); err == nil {
t.Fatal("durable recording failure was ignored")
}
durable.err = nil
if _, err := service.RecordProviderAllocation(context.Background(), provider.result, time.Unix(1001, 0)); err != nil {
t.Fatalf("provider recovery failed: %v", err)
}
if quota.calls != 1 || durable.calls != 2 {
t.Fatalf("quota/durable calls = %d/%d, want 1/2", quota.calls, durable.calls)
}
}