feat(routing): 完善平台满载避让与故障轮转

为未配置并发上限的平台增加基于运行和等待任务数的软负载,并按非满载、有效优先级、缓存亲和与负载稳定排序。\n\n平台模型 RPM、TPM 和并发额度竞争失败时只轮转候选,不触发冷却、禁用或降级;用户组额度保持不可绕过。补齐异步冷却排队恢复、满载原因、选择原因与低基数指标。\n\n验证:go test ./...;go vet ./...;PostgreSQL 原子额度、准入队列、Worker 容量回收及故障策略 HTTP acceptance。
This commit is contained in:
2026-08-03 17:42:34 +08:00
parent b125599354
commit 8362d6d27a
15 changed files with 468 additions and 152 deletions
+22 -16
View File
@@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"encoding/json"
"errors"
"strings"
"time"
@@ -200,25 +201,30 @@ WHERE id = $1::uuid`, platformModelID, cooldownSeconds)
return err
}
func (s *Store) RuntimeCandidateAvailable(ctx context.Context, platformID string, platformModelID string) (bool, error) {
func (s *Store) RuntimeCandidateAvailability(ctx context.Context, platformID string, platformModelID string) (bool, string, error) {
if strings.TrimSpace(platformID) == "" || strings.TrimSpace(platformModelID) == "" {
return false, nil
return false, "disabled_skipped", nil
}
var available bool
var reason string
err := s.pool.QueryRow(ctx, `
SELECT EXISTS (
SELECT 1
FROM platform_models model
JOIN integration_platforms platform ON platform.id = model.platform_id
WHERE platform.id = $1::uuid
AND model.id = $2::uuid
AND platform.status = 'enabled'
AND platform.deleted_at IS NULL
AND (platform.cooldown_until IS NULL OR platform.cooldown_until <= now())
AND model.enabled = true
AND (model.cooldown_until IS NULL OR model.cooldown_until <= now())
)`, platformID, platformModelID).Scan(&available)
return available, err
SELECT CASE
WHEN platform.deleted_at IS NOT NULL OR platform.status <> 'enabled' OR model.enabled = false
THEN 'disabled_skipped'
WHEN platform.cooldown_until > now() OR model.cooldown_until > now()
THEN 'cooldown_skipped'
ELSE ''
END
FROM platform_models model
JOIN integration_platforms platform ON platform.id = model.platform_id
WHERE platform.id = $1::uuid
AND model.id = $2::uuid`, platformID, platformModelID).Scan(&reason)
if errors.Is(err, pgx.ErrNoRows) {
return false, "disabled_skipped", nil
}
if err != nil {
return false, "", err
}
return reason == "", reason, nil
}
func (s *Store) ApplyCandidateFailureEffect(ctx context.Context, input CandidateFailureEffectInput) (CandidateFailureEffectResult, error) {