Commit a425911
committed
feat(scheduler,apikey): bounded session affinity + per-key limits
Two related backend enhancements addressing #150 and #146.
Scheduler (#150 — "round_robin still hammering one account"):
- Add bounded session affinity. sessionAffinity now tracks boundAt /
requestCount, and NextForSessionWithFilter escapes the binding when
any of:
• requestCount >= 50
• bound for >= 5 minutes
• bound account is no longer in the healthy tier
This preserves prompt-cache reuse on hot sessions while preventing
any single account from absorbing all traffic.
- Add Store.GetAffinityMode/SetAffinityMode (bounded/off/strict). Off
means every request re-picks via the scheduler; strict is the legacy
behavior. system_settings.affinity_mode persists the choice.
- FastScheduler in round_robin mode now sorts the healthy bucket by
7d usage ASC before round-robining, so the under-used accounts win
the next slot naturally.
API Keys (#146 — "support per-key 5h/7d quota and model restrictions"):
- Add api_keys.limits JSONB column carrying APIKeyLimits:
model_allow / model_deny (whitelist takes priority)
rpm, rpd
cost_limit_5h, cost_limit_7d
token_limit_5h, token_limit_7d
- New proxy/apikey_limits.go performs the checks before upstream
dispatch: O(1) model set check, plus sliding-window aggregation over
usage_logs (cached 60s in Redis, falls back to DB). Limited keys
bypass the runtime cache so PATCH takes effect immediately.
- 403 (permission_error) for model-denied, 429 (rate_limit_reached)
for quota windows. Wired into ChatCompletions, Responses, anthropic,
and images handlers.
Tested end-to-end against 2004 instance: model whitelist returns 403
for disallowed model, rpm=2 returns 429 after 10 injected usage rows
in the last minute, settings persistence verified.1 parent 265f67b commit a425911
13 files changed
Lines changed: 672 additions & 44 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
237 | 237 | | |
238 | 238 | | |
239 | 239 | | |
| 240 | + | |
240 | 241 | | |
241 | 242 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3388 | 3388 | | |
3389 | 3389 | | |
3390 | 3390 | | |
3391 | | - | |
3392 | | - | |
3393 | | - | |
3394 | | - | |
3395 | | - | |
3396 | | - | |
3397 | | - | |
| 3391 | + | |
| 3392 | + | |
| 3393 | + | |
| 3394 | + | |
| 3395 | + | |
| 3396 | + | |
| 3397 | + | |
| 3398 | + | |
3398 | 3399 | | |
3399 | 3400 | | |
3400 | 3401 | | |
| |||
3486 | 3487 | | |
3487 | 3488 | | |
3488 | 3489 | | |
| 3490 | + | |
| 3491 | + | |
| 3492 | + | |
| 3493 | + | |
| 3494 | + | |
3489 | 3495 | | |
3490 | 3496 | | |
3491 | 3497 | | |
3492 | 3498 | | |
3493 | 3499 | | |
3494 | 3500 | | |
| 3501 | + | |
3495 | 3502 | | |
3496 | 3503 | | |
3497 | 3504 | | |
| |||
3525 | 3532 | | |
3526 | 3533 | | |
3527 | 3534 | | |
3528 | | - | |
3529 | | - | |
3530 | | - | |
3531 | | - | |
3532 | | - | |
3533 | | - | |
| 3535 | + | |
| 3536 | + | |
| 3537 | + | |
| 3538 | + | |
| 3539 | + | |
| 3540 | + | |
| 3541 | + | |
3534 | 3542 | | |
3535 | 3543 | | |
3536 | 3544 | | |
| |||
3623 | 3631 | | |
3624 | 3632 | | |
3625 | 3633 | | |
| 3634 | + | |
| 3635 | + | |
| 3636 | + | |
| 3637 | + | |
3626 | 3638 | | |
3627 | 3639 | | |
3628 | 3640 | | |
| |||
3634 | 3646 | | |
3635 | 3647 | | |
3636 | 3648 | | |
| 3649 | + | |
| 3650 | + | |
| 3651 | + | |
| 3652 | + | |
| 3653 | + | |
| 3654 | + | |
| 3655 | + | |
| 3656 | + | |
| 3657 | + | |
| 3658 | + | |
| 3659 | + | |
| 3660 | + | |
| 3661 | + | |
| 3662 | + | |
| 3663 | + | |
| 3664 | + | |
| 3665 | + | |
| 3666 | + | |
| 3667 | + | |
| 3668 | + | |
| 3669 | + | |
| 3670 | + | |
| 3671 | + | |
| 3672 | + | |
| 3673 | + | |
| 3674 | + | |
| 3675 | + | |
| 3676 | + | |
| 3677 | + | |
| 3678 | + | |
| 3679 | + | |
| 3680 | + | |
| 3681 | + | |
| 3682 | + | |
| 3683 | + | |
| 3684 | + | |
| 3685 | + | |
| 3686 | + | |
| 3687 | + | |
| 3688 | + | |
| 3689 | + | |
| 3690 | + | |
| 3691 | + | |
| 3692 | + | |
| 3693 | + | |
| 3694 | + | |
| 3695 | + | |
| 3696 | + | |
| 3697 | + | |
| 3698 | + | |
| 3699 | + | |
| 3700 | + | |
| 3701 | + | |
| 3702 | + | |
| 3703 | + | |
| 3704 | + | |
| 3705 | + | |
3637 | 3706 | | |
3638 | 3707 | | |
3639 | 3708 | | |
| |||
3764 | 3833 | | |
3765 | 3834 | | |
3766 | 3835 | | |
| 3836 | + | |
3767 | 3837 | | |
3768 | 3838 | | |
3769 | 3839 | | |
| |||
3824 | 3894 | | |
3825 | 3895 | | |
3826 | 3896 | | |
| 3897 | + | |
3827 | 3898 | | |
3828 | 3899 | | |
3829 | 3900 | | |
| |||
3966 | 4037 | | |
3967 | 4038 | | |
3968 | 4039 | | |
| 4040 | + | |
3969 | 4041 | | |
3970 | 4042 | | |
3971 | 4043 | | |
| |||
4208 | 4280 | | |
4209 | 4281 | | |
4210 | 4282 | | |
| 4283 | + | |
| 4284 | + | |
| 4285 | + | |
| 4286 | + | |
| 4287 | + | |
4211 | 4288 | | |
4212 | 4289 | | |
4213 | 4290 | | |
| |||
4451 | 4528 | | |
4452 | 4529 | | |
4453 | 4530 | | |
| 4531 | + | |
4454 | 4532 | | |
4455 | 4533 | | |
4456 | 4534 | | |
| |||
4516 | 4594 | | |
4517 | 4595 | | |
4518 | 4596 | | |
| 4597 | + | |
4519 | 4598 | | |
4520 | 4599 | | |
4521 | 4600 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
62 | 63 | | |
63 | 64 | | |
64 | 65 | | |
| |||
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
| 87 | + | |
86 | 88 | | |
87 | 89 | | |
88 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
392 | 392 | | |
393 | 393 | | |
394 | 394 | | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
395 | 413 | | |
396 | 414 | | |
397 | 415 | | |
| |||
0 commit comments