Evict banned users from free_session slots each admission tick#526
Evict banned users from free_session slots each admission tick#526
Conversation
Greptile SummaryThis PR fixes a gap where banned users were retaining admitted Key changes:
Confidence Score: 5/5Safe to merge — the change is additive, well-tested, and fixes a real production data hygiene issue with no risk of data loss for legitimate users The implementation is correct: DELETE + EXISTS is idiomatic and safe, the no-status-filter behavior is intentional and correct (banned queued users should also be removed), both operations complete before admission so freed slots are visible to the same tick, and 2 targeted tests cover the new code paths including the edge case of health-paused admission. No interfaces are broken, no migrations required, and the change degrades gracefully (worst case: zero rows deleted is a no-op). No files require special attention Important Files Changed
Sequence DiagramsequenceDiagram
participant Ticker as runTick (setInterval)
participant Tick as runAdmissionTick
participant Sweep as sweepExpired
participant Evict as evictBanned
participant Health as getFleetHealth
participant Admit as admitFromQueue (per model)
participant DB as PostgreSQL
Ticker->>Tick: call every ADMISSION_TICK_MS
par parallel cleanup
Tick->>Sweep: sweepExpired(now, graceMs)
Sweep->>DB: DELETE active rows past expires_at+grace
DB-->>Sweep: deleted count
Sweep-->>Tick: expired
and
Tick->>Evict: evictBanned()
Evict->>DB: DELETE free_session WHERE EXISTS (banned user)
DB-->>Evict: deleted count
Evict-->>Tick: evictedBanned
end
Tick->>Health: getFleetHealth()
Health-->>Tick: FleetHealth map
loop per model
Tick->>Admit: admitFromQueue(model, health)
Admit->>DB: pg_try_advisory_xact_lock + SELECT queued + UPDATE to active
DB-->>Admit: admitted row or empty
Admit-->>Tick: { admitted, skipped }
end
Tick-->>Ticker: AdmissionTickResult { expired, evictedBanned, admitted, ... }
Ticker->>Ticker: logger.info(metric: freebuff_waiting_room)
Reviews (1): Last reviewed commit: "Evict banned users from free_session slo..." | Re-trigger Greptile |
Summary
~55 banned users were sitting on admitted
free_sessionslots becausebanUser()(Stripe webhook, admin UI, direct SQL) doesn't cascade intofree_session— only the one-shotscripts/ban-freebuff-bots.tshappened to delete those rows. AddsevictBanned()instore.tsand calls it fromrunAdmissionTickin parallel withsweepExpired, so every tick drops anyfree_sessionrow whose user hasbanned = true. The tick result and per-tick log line now surfaceevictedBannedfor observability.Test plan
bun run test src/server/free-session/__tests__/— 52/52 pass (includes two new tests: per-tick eviction + eviction continues when health pauses admission)tsc --noEmit -p webcleanevictedBannedcount drain the ~55 stale rows🤖 Generated with Claude Code