channel_select.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package service
  2. import (
  3. "errors"
  4. "github.com/QuantumNous/new-api/common"
  5. "github.com/QuantumNous/new-api/constant"
  6. "github.com/QuantumNous/new-api/logger"
  7. "github.com/QuantumNous/new-api/model"
  8. "github.com/QuantumNous/new-api/setting"
  9. "github.com/gin-gonic/gin"
  10. )
  11. // CacheGetRandomSatisfiedChannel tries to get a random channel that satisfies the requirements.
  12. func CacheGetRandomSatisfiedChannel(c *gin.Context, group string, modelName string, retry int) (*model.Channel, string, error) {
  13. var channel *model.Channel
  14. var err error
  15. selectGroup := group
  16. userGroup := common.GetContextKeyString(c, constant.ContextKeyUserGroup)
  17. if group == "auto" {
  18. if len(setting.GetAutoGroups()) == 0 {
  19. return nil, selectGroup, errors.New("auto groups is not enabled")
  20. }
  21. autoGroups := GetUserAutoGroup(userGroup)
  22. // 如果 token 启用了跨分组重试,获取上次失败的 auto group 索引,从下一个开始尝试
  23. startIndex := 0
  24. crossGroupRetry := common.GetContextKeyBool(c, constant.ContextKeyTokenCrossGroupRetry)
  25. if crossGroupRetry && retry > 0 {
  26. logger.LogDebug(c, "Auto group retry cross group, retry: %d", retry)
  27. if lastIndex, exists := common.GetContextKey(c, constant.ContextKeyAutoGroupIndex); exists {
  28. if idx, ok := lastIndex.(int); ok {
  29. startIndex = idx + 1
  30. }
  31. }
  32. logger.LogDebug(c, "Auto group retry cross group, start index: %d", startIndex)
  33. }
  34. for i := startIndex; i < len(autoGroups); i++ {
  35. autoGroup := autoGroups[i]
  36. logger.LogDebug(c, "Auto selecting group: %s", autoGroup)
  37. channel, _ = model.GetRandomSatisfiedChannel(autoGroup, modelName, 0)
  38. if channel == nil {
  39. continue
  40. } else {
  41. c.Set("auto_group", autoGroup)
  42. common.SetContextKey(c, constant.ContextKeyAutoGroupIndex, i)
  43. selectGroup = autoGroup
  44. logger.LogDebug(c, "Auto selected group: %s", autoGroup)
  45. break
  46. }
  47. }
  48. } else {
  49. channel, err = model.GetRandomSatisfiedChannel(group, modelName, retry)
  50. if err != nil {
  51. return nil, group, err
  52. }
  53. }
  54. return channel, selectGroup, nil
  55. }