feat(queue): 增加非文本模型分布式准入队列
使用 PostgreSQL 统一同步与异步非文本任务的并发准入、持久化等待和 Worker 容量分配,并将生产 API 与独立 Worker 角色拆分。 补充策略管理、共享契约、OpenAPI、Kubernetes 双节点 Worker 清单及跨节点验收脚本;未默认启用任何生产 queue_size 策略。 已在原基线完成 Go、前端、迁移、Shell、Kustomize 与长任务容量验收;合入最新主干后将重新执行发布门禁。
This commit is contained in:
@@ -81,6 +81,74 @@ func (s *Service) rateLimitReservations(ctx context.Context, user *auth.User, ca
|
||||
return out
|
||||
}
|
||||
|
||||
func (s *Service) admissionScopes(ctx context.Context, user *auth.User, candidate store.RuntimeModelCandidate) ([]store.AdmissionScope, string) {
|
||||
scopes := make([]store.AdmissionScope, 0, 2)
|
||||
platformPolicy := effectiveRateLimitPolicy(candidate)
|
||||
if scope, ok := admissionScopeFromPolicy(
|
||||
"platform_model",
|
||||
candidate.PlatformModelID,
|
||||
firstNonEmptyString(candidate.DisplayName, candidate.ModelAlias, candidate.ModelName),
|
||||
map[string]any{
|
||||
"platformId": candidate.PlatformID,
|
||||
"platformName": candidate.PlatformName,
|
||||
"modelAlias": candidate.ModelAlias,
|
||||
"modelName": candidate.ModelName,
|
||||
},
|
||||
platformPolicy,
|
||||
); ok {
|
||||
scopes = append(scopes, scope)
|
||||
}
|
||||
groupID := ""
|
||||
if group, err := s.store.ResolveUserGroupPolicy(ctx, user); err == nil && group.ID != "" {
|
||||
groupPolicy := store.NormalizeRateLimitPolicy(group.RateLimitPolicy)
|
||||
if scope, ok := admissionScopeFromPolicy(
|
||||
"user_group",
|
||||
group.ID,
|
||||
firstNonEmptyString(group.Name, group.GroupKey),
|
||||
map[string]any{"groupKey": group.GroupKey, "name": group.Name},
|
||||
groupPolicy,
|
||||
); ok {
|
||||
groupID = group.ID
|
||||
scopes = append(scopes, scope)
|
||||
}
|
||||
}
|
||||
return scopes, groupID
|
||||
}
|
||||
|
||||
func admissionScopeFromPolicy(scopeType string, scopeKey string, scopeName string, metadata map[string]any, policy map[string]any) (store.AdmissionScope, bool) {
|
||||
concurrentLimit, hasConcurrent := store.RateLimitPolicyMetric(policy, "concurrent")
|
||||
queueRule, hasQueue := store.QueueRuleFromPolicy(policy)
|
||||
if !hasConcurrent && !hasQueue {
|
||||
return store.AdmissionScope{}, false
|
||||
}
|
||||
scope := store.AdmissionScope{
|
||||
ScopeType: scopeType,
|
||||
ScopeKey: scopeKey,
|
||||
ScopeName: scopeName,
|
||||
ScopeMetadata: metadata,
|
||||
ConcurrentLimit: concurrentLimit,
|
||||
Amount: 1,
|
||||
LeaseTTLSeconds: 120,
|
||||
Policy: policy,
|
||||
}
|
||||
if hasQueue {
|
||||
scope.QueueLimit = queueRule.Limit
|
||||
scope.MaxWaitSeconds = queueRule.MaxWaitSeconds
|
||||
}
|
||||
rules, _ := store.NormalizeRateLimitPolicy(policy)["rules"].([]any)
|
||||
for _, rawRule := range rules {
|
||||
rule, _ := rawRule.(map[string]any)
|
||||
if strings.TrimSpace(stringFromMap(rule, "metric")) != "concurrent" {
|
||||
continue
|
||||
}
|
||||
if ttl := int(floatFromAny(rule["leaseTtlSeconds"])); ttl > 0 {
|
||||
scope.LeaseTTLSeconds = ttl
|
||||
}
|
||||
break
|
||||
}
|
||||
return scope, true
|
||||
}
|
||||
|
||||
func effectiveRateLimitPolicy(candidate store.RuntimeModelCandidate) map[string]any {
|
||||
return store.EffectiveRateLimitPolicy(store.EffectiveRateLimitPolicyInput{
|
||||
BasePolicy: candidate.BaseRateLimitPolicy,
|
||||
@@ -118,7 +186,7 @@ func reservationsFromPolicy(scopeType string, scopeKey string, scopeName string,
|
||||
rule, _ := rawRule.(map[string]any)
|
||||
metric := strings.TrimSpace(stringFromMap(rule, "metric"))
|
||||
limit := floatFromAny(rule["limit"])
|
||||
if metric == "" || limit <= 0 {
|
||||
if metric == "" || metric == "queue_size" || limit <= 0 {
|
||||
continue
|
||||
}
|
||||
amount := 1.0
|
||||
|
||||
Reference in New Issue
Block a user