perf(admin): cache the suspension gate lookup
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 46s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m4s

The suspension gate runs CurrentSuspension on every authenticated request. Add a write-through in-memory cache on account.Store keyed by account id, invalidated on Suspend/LiftSuspension, with the cached entry re-evaluated against the wall clock so a temporary block lapses without an explicit invalidation. Single-instance, matching the deployment (one shared Store). Keeps the gate off the database on the hot path while a block still takes effect on the next request.
This commit is contained in:
Ilia Denisov
2026-06-14 22:24:57 +02:00
parent d1ba666495
commit 290874720f
3 changed files with 138 additions and 1 deletions
+4 -1
View File
@@ -99,12 +99,15 @@ type Identity struct {
type Store struct {
db *sql.DB
metrics *accountMetrics
// suspensions caches each account's current manual block, read by the suspension gate on
// every authenticated request and invalidated on Suspend/LiftSuspension. See suspension.go.
suspensions *suspensionCache
}
// NewStore constructs a Store wrapping db. Metrics default to a no-op meter until
// SetMetrics installs the real one during startup wiring.
func NewStore(db *sql.DB) *Store {
return &Store{db: db, metrics: defaultAccountMetrics()}
return &Store{db: db, metrics: defaultAccountMetrics(), suspensions: newSuspensionCache()}
}
// ProvisionByIdentity returns the account bound to (kind, externalID), creating