refactor(grok): 移除未接入的免费恢复状态

This commit is contained in:
IanShaw027
2026-08-07 15:03:04 +08:00
parent 2e20ea4c87
commit a397724f69
3 changed files with 0 additions and 100 deletions
@@ -1,87 +0,0 @@
package service
import (
"strings"
"sync"
"time"
)
// Lightweight free-usage recovery hint: after free cool ends, keep a short
// "probe preferred" window so the next scheduling pass can prefer accounts that
// have waited out free-usage without immediately re-entering a tight 429 loop.
// Full async quota recovery queues (grok2api) are intentionally not ported.
type grokFreeRecoveryHint struct {
CoolUntil time.Time
ProbeUntil time.Time
}
type grokFreeRecoveryStore struct {
mu sync.Mutex
items map[int64]grokFreeRecoveryHint
}
var globalGrokFreeRecovery = &grokFreeRecoveryStore{
items: make(map[int64]grokFreeRecoveryHint),
}
const grokFreeRecoveryProbeWindow = 30 * time.Minute
// markGrokFreeUsageRecovery records that account left free-usage cool and should
// be treated carefully until ProbeUntil.
func markGrokFreeUsageRecovery(accountID int64, coolUntil time.Time) {
if accountID <= 0 {
return
}
now := time.Now()
if coolUntil.IsZero() || !coolUntil.After(now) {
coolUntil = now.Add(2 * time.Hour)
}
globalGrokFreeRecovery.mu.Lock()
defer globalGrokFreeRecovery.mu.Unlock()
globalGrokFreeRecovery.items[accountID] = grokFreeRecoveryHint{
CoolUntil: coolUntil,
ProbeUntil: coolUntil.Add(grokFreeRecoveryProbeWindow),
}
}
// isGrokFreeUsageCooling is true while still inside the free-usage cool window.
func isGrokFreeUsageCooling(accountID int64, now time.Time) bool {
if accountID <= 0 {
return false
}
globalGrokFreeRecovery.mu.Lock()
defer globalGrokFreeRecovery.mu.Unlock()
h, ok := globalGrokFreeRecovery.items[accountID]
if !ok {
return false
}
if now.After(h.ProbeUntil) {
delete(globalGrokFreeRecovery.items, accountID)
return false
}
return now.Before(h.CoolUntil)
}
// isGrokFreeUsageProbePreferred is true after cool ends but before probe window
// expires — account is schedulable but may still be near free-usage edges.
func isGrokFreeUsageProbePreferred(accountID int64, now time.Time) bool {
if accountID <= 0 {
return false
}
globalGrokFreeRecovery.mu.Lock()
defer globalGrokFreeRecovery.mu.Unlock()
h, ok := globalGrokFreeRecovery.items[accountID]
if !ok {
return false
}
if now.After(h.ProbeUntil) {
delete(globalGrokFreeRecovery.items, accountID)
return false
}
return !now.Before(h.CoolUntil) && now.Before(h.ProbeUntil)
}
// reasonIsGrokFreeUsage detects free-usage cool reasons written by our handlers.
func reasonIsGrokFreeUsage(reason string) bool {
return strings.Contains(strings.ToLower(reason), "free usage")
}
-11
View File
@@ -57,17 +57,6 @@ func TestGrokStickyAffinitySeed_ScopesByModel(t *testing.T) {
require.Contains(t, a, "grok-affinity:v1:")
}
func TestGrokFreeUsageRecoveryHints(t *testing.T) {
id := int64(9001)
coolUntil := time.Now().Add(time.Hour)
markGrokFreeUsageRecovery(id, coolUntil)
require.True(t, isGrokFreeUsageCooling(id, time.Now()))
require.False(t, isGrokFreeUsageProbePreferred(id, time.Now()))
// After cool: probe preferred
require.True(t, isGrokFreeUsageProbePreferred(id, coolUntil.Add(time.Minute)))
require.False(t, isGrokFreeUsageCooling(id, coolUntil.Add(time.Minute)))
}
func TestExtractGrokModelIDsFromModelsBody(t *testing.T) {
body := []byte(`{"object":"list","data":[{"id":"grok-4.5"},{"id":"grok-4.3"},{"id":"grok-4.5"}]}`)
ids := extractGrokModelIDsFromModelsBody(body)
@@ -485,8 +485,6 @@ func (s *OpenAIGatewayService) applyGrokUpstreamFailureDecision(
// of rotation.
return true
}
coolUntil := time.Now().Add(decision.Cooldown)
markGrokFreeUsageRecovery(account.ID, coolUntil)
case GrokFailureBilling:
low := strings.ToLower(decision.Reason)
if strings.Contains(low, "spending") || strings.Contains(low, "credits") {