openai_403_counter_cache.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package repository
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/Wei-Shaw/sub2api/internal/service"
  6. "github.com/redis/go-redis/v9"
  7. )
  8. const openAI403CounterPrefix = "openai_403_count:account:"
  9. var openAI403CounterIncrScript = redis.NewScript(`
  10. local key = KEYS[1]
  11. local ttl = tonumber(ARGV[1])
  12. local count = redis.call('INCR', key)
  13. if count == 1 then
  14. redis.call('EXPIRE', key, ttl)
  15. end
  16. return count
  17. `)
  18. type openAI403CounterCache struct {
  19. rdb *redis.Client
  20. }
  21. func NewOpenAI403CounterCache(rdb *redis.Client) service.OpenAI403CounterCache {
  22. return &openAI403CounterCache{rdb: rdb}
  23. }
  24. func (c *openAI403CounterCache) IncrementOpenAI403Count(ctx context.Context, accountID int64, windowMinutes int) (int64, error) {
  25. key := fmt.Sprintf("%s%d", openAI403CounterPrefix, accountID)
  26. ttlSeconds := windowMinutes * 60
  27. if ttlSeconds < 60 {
  28. ttlSeconds = 60
  29. }
  30. result, err := openAI403CounterIncrScript.Run(ctx, c.rdb, []string{key}, ttlSeconds).Int64()
  31. if err != nil {
  32. return 0, fmt.Errorf("increment openai 403 count: %w", err)
  33. }
  34. return result, nil
  35. }
  36. func (c *openAI403CounterCache) ResetOpenAI403Count(ctx context.Context, accountID int64) error {
  37. key := fmt.Sprintf("%s%d", openAI403CounterPrefix, accountID)
  38. return c.rdb.Del(ctx, key).Err()
  39. }