setting_openai_apikey_health.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "time"
  9. )
  10. const openAIAPIKeyHealthBreakerSettingsCacheTTL = 30 * time.Second
  11. type cachedOpenAIAPIKeyHealthBreakerSettings struct {
  12. settings OpenAIAPIKeyHealthBreakerSettings
  13. expiresAt time.Time
  14. }
  15. func normalizeOpenAIAPIKeyHealthBreakerSettings(settings *OpenAIAPIKeyHealthBreakerSettings) *OpenAIAPIKeyHealthBreakerSettings {
  16. if settings == nil {
  17. return DefaultOpenAIAPIKeyHealthBreakerSettings()
  18. }
  19. result := *settings
  20. if result.WindowMinutes < 1 {
  21. result.WindowMinutes = 1
  22. } else if result.WindowMinutes > 60 {
  23. result.WindowMinutes = 60
  24. }
  25. if result.FailureThreshold < 1 {
  26. result.FailureThreshold = 1
  27. } else if result.FailureThreshold > 10000 {
  28. result.FailureThreshold = 10000
  29. }
  30. if result.CooldownMinutes < 1 {
  31. result.CooldownMinutes = 1
  32. } else if result.CooldownMinutes > 60 {
  33. result.CooldownMinutes = 60
  34. }
  35. return &result
  36. }
  37. func (s *SettingService) GetOpenAIAPIKeyHealthBreakerSettings(ctx context.Context) (*OpenAIAPIKeyHealthBreakerSettings, error) {
  38. if s == nil || s.settingRepo == nil {
  39. return DefaultOpenAIAPIKeyHealthBreakerSettings(), nil
  40. }
  41. if cached, ok := s.openAIAPIKeyHealthBreakerCache.Load().(*cachedOpenAIAPIKeyHealthBreakerSettings); ok && cached != nil && time.Now().Before(cached.expiresAt) {
  42. result := cached.settings
  43. return &result, nil
  44. }
  45. settings := DefaultOpenAIAPIKeyHealthBreakerSettings()
  46. value, err := s.settingRepo.GetValue(ctx, SettingKeyOpenAIAPIKeyHealthBreakerSettings)
  47. if err != nil && !errors.Is(err, ErrSettingNotFound) {
  48. return nil, fmt.Errorf("get OpenAI API key health breaker settings: %w", err)
  49. }
  50. if err == nil && strings.TrimSpace(value) != "" {
  51. var stored OpenAIAPIKeyHealthBreakerSettings
  52. if json.Unmarshal([]byte(value), &stored) == nil {
  53. settings = normalizeOpenAIAPIKeyHealthBreakerSettings(&stored)
  54. }
  55. }
  56. s.openAIAPIKeyHealthBreakerCache.Store(&cachedOpenAIAPIKeyHealthBreakerSettings{
  57. settings: *settings,
  58. expiresAt: time.Now().Add(openAIAPIKeyHealthBreakerSettingsCacheTTL),
  59. })
  60. result := *settings
  61. return &result, nil
  62. }