fix(api): don't burn wake cooldown when refused at capacity
A wake refused by the §9.1 running-server cap returns 503, but the per-server cooldown was recorded before the cap check ran. A player held because the cluster was momentarily full would then also have to wait out the wake cooldown once a slot freed, even though their refused wake never actually flipped desiredState. Split cooldownLimiter.allow into allowed (peek, no record) and record (commit). Both wake paths now consult allowed for the 429, then call record only after SetDesiredState succeeds — so neither a 503 at_capacity nor a SetDesiredState error consumes the cooldown. The split is safe against the running cap, which counts CRD truth via ListServers and is independent of the limiter.
This commit is contained in:
4 files changed
+69
-7
No files matched your search
@@ -39,7 +39,7 @@ func (a *API) handleWake(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, r, err)
|
||||
return
|
||||
}
|
||||
if !a.limiter().allow(name, a.WakeCooldown) {
|
||||
if !a.limiter().allowed(name, a.WakeCooldown) {
|
||||
writeError(w, r, newError(http.StatusTooManyRequests, "cooldown", "wake is cooling down, retry shortly"))
|
||||
return
|
||||
}
|
||||
@@ -60,6 +60,11 @@ func (a *API) handleWake(w http.ResponseWriter, r *http.Request) {
|
||||
writeError(w, r, err)
|
||||
return
|
||||
}
|
||||
// The wake actually flipped, so consume the per-server cooldown only now: a 503
|
||||
// at_capacity or the SetDesiredState failure above must not burn it (a player
|
||||
// held at capacity should retry the instant a slot frees, not wait out a
|
||||
// cooldown their refused wake never earned).
|
||||
a.limiter().record(name)
|
||||
a.audit(r, p.Email, "wake", name)
|
||||
writeJSON(w, http.StatusAccepted, map[string]any{"name": name, "desiredState": "Running"})
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user