litellm/ruff-strict-budget.json
ryan-crabbe-berri c40828509b
fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287)
* fix(reset_budget_job): advance budget_reset_at atomically with the spend cascade

A postgres timeout mid-cascade previously left LiteLLM_BudgetTable rows
stamped for the next window while team member, enduser, org and tag spend
stayed at cap, so every later tick skipped them until the window rolled
over. All cascade writes and the budget_reset_at advance now share one
prisma batch transaction; a failed run persists nothing and the rows stay
due for the next ~10 minute tick. Cache and counter invalidation runs only
after commit, and the catch-all enduser log line now names the cascade.

* fix(reset_budget_job): elect one runner per tick and chunk the reset scans

Every pod and worker previously ran the reset job every ~10 minutes,
each fetching every expired row with no limit and writing one giant
transaction at the same calendar-aligned boundary; that concurrency is
what piled up postgres lock contention and timeouts. The job now takes
the shared PodLockManager redis lock (no redis keeps the old behavior),
and each phase walks its due rows in 500-row chunks, one transaction per
chunk, stopping when a chunk is short, makes no forward progress, or
hits the per-run cap; leftovers wait for the next tick.

* chore(lint): ratchet budget ceilings down for fixed violations

* fix(reset_budget_job): harden chunk loop, fail open on redis errors, heartbeat the lock

Review fixes on the two prior commits. Reset scans now skip rows with no
budget_duration, so permanently due rows can neither starve a phase nor
have a lifetime cap zeroed every tick. Chunk progress counts rows whose
new budget_reset_at actually cleared the cutoff, so a zero-length
duration cannot burn the per-run chunk cap. A failed lock acquire only
skips the run when another pod verifiably holds the lock; a broken redis
runs unguarded instead of silently disabling resets fleet-wide. Partial
row failures report real progress and fire the failure hook without
killing the phase. The leader re-asserts the lock between phases and
stops if another pod took over, and the budget window advance uses
update_many so a tier deleted mid-chunk cannot abort the transaction.
Lint budget ceilings re-ratcheted for the net-fixed violations.

* fix(reset_budget_job): renew the leader lease and reject non-positive budget durations

Bot review follow-ups. PodLockManager now extends the lock TTL when the
holding pod re-acquires, via an atomic compare-and-expire script with a
plain SET fallback, so a run longer than the TTL keeps its lease instead
of silently sharing the job with another pod. The positive-duration
validation that team member endpoints already had is hoisted to
management common_utils and applied to key, internal user, budget,
customer and team intake, so a tenant can no longer create zero-duration
budgets whose permanently due rows starve other tenants' resets. Such
durations now return 400 at intake; existing rows are untouched.

* refactor(reset_budget_job): defer leader election to a follow-up PR

* fix(reset_budget_job): satisfy strict lint gates

String defaults for the two getenv calls (PLW1508) and the chunk
outcome returns moved to try/else (TRY300).
2026-08-10 14:42:36 -07:00

263 lines
2.9 KiB
JSON

{
"ANN001": {
"limit": 3106
},
"ANN002": {
"limit": 71
},
"ANN003": {
"limit": 832
},
"ANN201": {
"limit": 2023
},
"ANN202": {
"limit": 860
},
"ANN204": {
"limit": 713
},
"ANN205": {
"limit": 114
},
"ANN206": {
"limit": 133
},
"ANN401": {
"limit": 1495
},
"ASYNC230": {
"limit": 11
},
"B004": {
"limit": 2
},
"B006": {
"limit": 178
},
"B008": {
"limit": 505
},
"B009": {
"limit": 79
},
"B010": {
"limit": 190
},
"B018": {
"limit": 2
},
"B019": {
"limit": 1
},
"B021": {
"limit": 1
},
"B026": {
"limit": 3
},
"BLE001": {
"limit": 2924
},
"C401": {
"limit": 8
},
"C404": {
"limit": 1
},
"C405": {
"limit": 19
},
"C408": {
"limit": 11
},
"C414": {
"limit": 4
},
"C419": {
"limit": 1
},
"C901": {
"limit": 313
},
"D419": {
"limit": 6
},
"DTZ001": {
"limit": 2
},
"DTZ003": {
"limit": 26
},
"DTZ005": {
"limit": 233
},
"DTZ006": {
"limit": 10
},
"DTZ007": {
"limit": 19
},
"DTZ011": {
"limit": 3
},
"EXE001": {
"limit": 4
},
"EXE002": {
"limit": 3
},
"F401": {
"limit": 17
},
"LOG015": {
"limit": 5
},
"N999": {
"limit": 1
},
"PERF102": {
"limit": 27
},
"PERF401": {
"limit": 12
},
"PERF403": {
"limit": 34
},
"PIE804": {
"limit": 18
},
"PIE810": {
"limit": 43
},
"PLC0206": {
"limit": 26
},
"PLC0414": {
"limit": 46
},
"PLR0124": {
"limit": 1
},
"PLR0206": {
"limit": 1
},
"PLR1704": {
"limit": 3
},
"PLR1714": {
"limit": 257
},
"PLW0127": {
"limit": 57
},
"PLW0133": {
"limit": 1
},
"PLW0602": {
"limit": 215
},
"PLW0603": {
"limit": 191
},
"PLW1508": {
"limit": 190
},
"PLW1510": {
"limit": 2
},
"PYI036": {
"limit": 3
},
"RET504": {
"limit": 177
},
"RUF012": {
"limit": 241
},
"RUF015": {
"limit": 8
},
"RUF019": {
"limit": 38
},
"RUF046": {
"limit": 4
},
"RUF059": {
"limit": 67
},
"RUF100": {
"limit": 0
},
"S110": {
"limit": 218
},
"S112": {
"limit": 22
},
"SIM101": {
"limit": 58
},
"SIM102": {
"limit": 322
},
"SIM103": {
"limit": 119
},
"SIM113": {
"limit": 3
},
"SIM115": {
"limit": 2
},
"SIM117": {
"limit": 7
},
"SIM201": {
"limit": 1
},
"SIM210": {
"limit": 8
},
"SIM211": {
"limit": 1
},
"SIM222": {
"limit": 1
},
"SIM401": {
"limit": 11
},
"TC004": {
"limit": 5
},
"TID251": {
"limit": 1226
},
"TRY002": {
"limit": 524
},
"TRY004": {
"limit": 96
},
"TRY201": {
"limit": 405
},
"TRY203": {
"limit": 113
},
"TRY300": {
"limit": 860
},
"UP028": {
"limit": 2
},
"UP031": {
"limit": 2
},
"UP036": {
"limit": 1
}
}