fix(后端): 修复 lint 失败并清理无用代码
修正测试中的 APIKey 名称引用 移除不可达返回与未使用函数 统一 gofmt 格式并处理 Close 错误
This commit is contained in:
@@ -497,9 +497,9 @@ func setDefaults() {
|
|||||||
viper.SetDefault("gateway.max_body_size", int64(100*1024*1024))
|
viper.SetDefault("gateway.max_body_size", int64(100*1024*1024))
|
||||||
viper.SetDefault("gateway.connection_pool_isolation", ConnectionPoolIsolationAccountProxy)
|
viper.SetDefault("gateway.connection_pool_isolation", ConnectionPoolIsolationAccountProxy)
|
||||||
// HTTP 上游连接池配置(针对 5000+ 并发用户优化)
|
// HTTP 上游连接池配置(针对 5000+ 并发用户优化)
|
||||||
viper.SetDefault("gateway.max_idle_conns", 240) // 最大空闲连接总数(HTTP/2 场景默认)
|
viper.SetDefault("gateway.max_idle_conns", 240) // 最大空闲连接总数(HTTP/2 场景默认)
|
||||||
viper.SetDefault("gateway.max_idle_conns_per_host", 120) // 每主机最大空闲连接(HTTP/2 场景默认)
|
viper.SetDefault("gateway.max_idle_conns_per_host", 120) // 每主机最大空闲连接(HTTP/2 场景默认)
|
||||||
viper.SetDefault("gateway.max_conns_per_host", 240) // 每主机最大连接数(含活跃,HTTP/2 场景默认)
|
viper.SetDefault("gateway.max_conns_per_host", 240) // 每主机最大连接数(含活跃,HTTP/2 场景默认)
|
||||||
viper.SetDefault("gateway.idle_conn_timeout_seconds", 90) // 空闲连接超时(秒)
|
viper.SetDefault("gateway.idle_conn_timeout_seconds", 90) // 空闲连接超时(秒)
|
||||||
viper.SetDefault("gateway.max_upstream_clients", 5000)
|
viper.SetDefault("gateway.max_upstream_clients", 5000)
|
||||||
viper.SetDefault("gateway.client_idle_ttl_seconds", 900)
|
viper.SetDefault("gateway.client_idle_ttl_seconds", 900)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ import (
|
|||||||
|
|
||||||
"github.com/Wei-Shaw/sub2api/internal/config"
|
"github.com/Wei-Shaw/sub2api/internal/config"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/pkg/antigravity"
|
"github.com/Wei-Shaw/sub2api/internal/pkg/antigravity"
|
||||||
pkgerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
|
||||||
"github.com/Wei-Shaw/sub2api/internal/pkg/claude"
|
"github.com/Wei-Shaw/sub2api/internal/pkg/claude"
|
||||||
|
pkgerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
|
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
|
||||||
middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware"
|
middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware"
|
||||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||||
|
|||||||
@@ -246,13 +246,3 @@ func createReqClient(proxyURL string) *req.Client {
|
|||||||
|
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
func prefix(s string, n int) string {
|
|
||||||
if n <= 0 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
if len(s) <= n {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
return s[:n]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -113,12 +113,12 @@ func TestApiKeyAuthWithSubscriptionGoogle_QueryApiKeyRejected(t *testing.T) {
|
|||||||
gin.SetMode(gin.TestMode)
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
apiKeyService := newTestApiKeyService(fakeApiKeyRepo{
|
apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{
|
||||||
getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) {
|
getByKey: func(ctx context.Context, key string) (*service.APIKey, error) {
|
||||||
return nil, errors.New("should not be called")
|
return nil, errors.New("should not be called")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{}))
|
r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, &config.Config{}))
|
||||||
r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) })
|
r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) })
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v1beta/test?api_key=legacy", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v1beta/test?api_key=legacy", nil)
|
||||||
@@ -137,9 +137,9 @@ func TestApiKeyAuthWithSubscriptionGoogle_QueryKeyAllowedOnV1Beta(t *testing.T)
|
|||||||
gin.SetMode(gin.TestMode)
|
gin.SetMode(gin.TestMode)
|
||||||
|
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
apiKeyService := newTestApiKeyService(fakeApiKeyRepo{
|
apiKeyService := newTestAPIKeyService(fakeAPIKeyRepo{
|
||||||
getByKey: func(ctx context.Context, key string) (*service.ApiKey, error) {
|
getByKey: func(ctx context.Context, key string) (*service.APIKey, error) {
|
||||||
return &service.ApiKey{
|
return &service.APIKey{
|
||||||
ID: 1,
|
ID: 1,
|
||||||
Key: key,
|
Key: key,
|
||||||
Status: service.StatusActive,
|
Status: service.StatusActive,
|
||||||
@@ -151,7 +151,7 @@ func TestApiKeyAuthWithSubscriptionGoogle_QueryKeyAllowedOnV1Beta(t *testing.T)
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
cfg := &config.Config{RunMode: config.RunModeSimple}
|
cfg := &config.Config{RunMode: config.RunModeSimple}
|
||||||
r.Use(ApiKeyAuthWithSubscriptionGoogle(apiKeyService, nil, cfg))
|
r.Use(APIKeyAuthWithSubscriptionGoogle(apiKeyService, nil, cfg))
|
||||||
r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) })
|
r.GET("/v1beta/test", func(c *gin.Context) { c.JSON(200, gin.H{"ok": true}) })
|
||||||
|
|
||||||
req := httptest.NewRequest(http.MethodGet, "/v1beta/test?key=valid", nil)
|
req := httptest.NewRequest(http.MethodGet, "/v1beta/test?key=valid", nil)
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
// 注:ErrInsufficientBalance在redeem_service.go中定义
|
// 注:ErrInsufficientBalance在redeem_service.go中定义
|
||||||
// 注:ErrDailyLimitExceeded/ErrWeeklyLimitExceeded/ErrMonthlyLimitExceeded在subscription_service.go中定义
|
// 注:ErrDailyLimitExceeded/ErrWeeklyLimitExceeded/ErrMonthlyLimitExceeded在subscription_service.go中定义
|
||||||
var (
|
var (
|
||||||
ErrSubscriptionInvalid = infraerrors.Forbidden("SUBSCRIPTION_INVALID", "subscription is invalid or expired")
|
ErrSubscriptionInvalid = infraerrors.Forbidden("SUBSCRIPTION_INVALID", "subscription is invalid or expired")
|
||||||
ErrBillingServiceUnavailable = infraerrors.ServiceUnavailable("BILLING_SERVICE_ERROR", "Billing service temporarily unavailable. Please retry later.")
|
ErrBillingServiceUnavailable = infraerrors.ServiceUnavailable("BILLING_SERVICE_ERROR", "Billing service temporarily unavailable. Please retry later.")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -73,10 +73,10 @@ type cacheWriteTask struct {
|
|||||||
// BillingCacheService 计费缓存服务
|
// BillingCacheService 计费缓存服务
|
||||||
// 负责余额和订阅数据的缓存管理,提供高性能的计费资格检查
|
// 负责余额和订阅数据的缓存管理,提供高性能的计费资格检查
|
||||||
type BillingCacheService struct {
|
type BillingCacheService struct {
|
||||||
cache BillingCache
|
cache BillingCache
|
||||||
userRepo UserRepository
|
userRepo UserRepository
|
||||||
subRepo UserSubscriptionRepository
|
subRepo UserSubscriptionRepository
|
||||||
cfg *config.Config
|
cfg *config.Config
|
||||||
circuitBreaker *billingCircuitBreaker
|
circuitBreaker *billingCircuitBreaker
|
||||||
|
|
||||||
cacheWriteChan chan cacheWriteTask
|
cacheWriteChan chan cacheWriteTask
|
||||||
@@ -659,28 +659,3 @@ func circuitStateString(state billingCircuitBreakerState) string {
|
|||||||
return "unknown"
|
return "unknown"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkSubscriptionLimitsFallback 降级检查订阅限额
|
|
||||||
func (s *BillingCacheService) checkSubscriptionLimitsFallback(subscription *UserSubscription, group *Group) error {
|
|
||||||
if subscription == nil {
|
|
||||||
return ErrSubscriptionInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subscription.IsActive() {
|
|
||||||
return ErrSubscriptionInvalid
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subscription.CheckDailyLimit(group, 0) {
|
|
||||||
return ErrDailyLimitExceeded
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subscription.CheckWeeklyLimit(group, 0) {
|
|
||||||
return ErrWeeklyLimitExceeded
|
|
||||||
}
|
|
||||||
|
|
||||||
if !subscription.CheckMonthlyLimit(group, 0) {
|
|
||||||
return ErrMonthlyLimitExceeded
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1731,7 +1731,6 @@ func (s *GatewayService) handleStreamingResponse(ctx context.Context, resp *http
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &streamingResult{usage: usage, firstTokenMs: firstTokenMs}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// replaceModelInSSELine 替换SSE数据行中的model字段
|
// replaceModelInSSELine 替换SSE数据行中的model字段
|
||||||
|
|||||||
@@ -934,7 +934,6 @@ func (s *OpenAIGatewayService) handleStreamingResponse(ctx context.Context, resp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &openaiStreamingResult{usage: usage, firstTokenMs: firstTokenMs}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *OpenAIGatewayService) replaceModelInSSELine(line, fromModel, toModel string) string {
|
func (s *OpenAIGatewayService) replaceModelInSSELine(line, fromModel, toModel string) string {
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ func TestOpenAIStreamingTooLong(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer pw.Close()
|
defer func() { _ = pw.Close() }()
|
||||||
// 写入超过 MaxLineSize 的单行数据,触发 ErrTooLong
|
// 写入超过 MaxLineSize 的单行数据,触发 ErrTooLong
|
||||||
payload := "data: " + strings.Repeat("a", 128*1024) + "\n"
|
payload := "data: " + strings.Repeat("a", 128*1024) + "\n"
|
||||||
_, _ = pw.Write([]byte(payload))
|
_, _ = pw.Write([]byte(payload))
|
||||||
|
|||||||
Reference in New Issue
Block a user