feat(queue): 增加非文本模型分布式准入队列
使用 PostgreSQL 统一同步与异步非文本任务的并发准入、持久化等待和 Worker 容量分配,并将生产 API 与独立 Worker 角色拆分。 补充策略管理、共享契约、OpenAPI、Kubernetes 双节点 Worker 清单及跨节点验收脚本;未默认启用任何生产 queue_size 策略。 已在原基线完成 Go、前端、迁移、Shell、Kustomize 与长任务容量验收;合入最新主干后将重新执行发布门禁。
This commit is contained in:
@@ -76,7 +76,11 @@ var (
|
||||
)
|
||||
|
||||
func Connect(ctx context.Context, databaseURL string) (*Store, error) {
|
||||
config, err := postgresPoolConfig(databaseURL)
|
||||
return ConnectWithMaxConns(ctx, databaseURL, 0)
|
||||
}
|
||||
|
||||
func ConnectWithMaxConns(ctx context.Context, databaseURL string, maxConns int) (*Store, error) {
|
||||
config, err := postgresPoolConfig(databaseURL, maxConns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -91,13 +95,16 @@ func Connect(ctx context.Context, databaseURL string) (*Store, error) {
|
||||
return &Store{pool: pool}, nil
|
||||
}
|
||||
|
||||
func postgresPoolConfig(databaseURL string) (*pgxpool.Config, error) {
|
||||
func postgresPoolConfig(databaseURL string, maxConns ...int) (*pgxpool.Config, error) {
|
||||
config, err := pgxpool.ParseConfig(databaseURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.ConnConfig.ConnectTimeout = postgresConnectTimeout
|
||||
config.ConnConfig.RuntimeParams["application_name"] = postgresApplicationName
|
||||
if len(maxConns) > 0 && maxConns[0] > 0 {
|
||||
config.MaxConns = int32(maxConns[0])
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
@@ -523,6 +530,8 @@ type GatewayTask struct {
|
||||
AsyncMode bool `json:"asyncMode"`
|
||||
RiverJobID int64 `json:"riverJobId,omitempty"`
|
||||
Status string `json:"status"`
|
||||
QueueKey string `json:"-"`
|
||||
Priority int `json:"-"`
|
||||
Cancellable *bool `json:"cancellable,omitempty"`
|
||||
Submitted *bool `json:"submitted,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
@@ -570,7 +579,8 @@ COALESCE(api_key_id, ''), COALESCE(api_key_name, ''), COALESCE(api_key_prefix, '
|
||||
COALESCE(user_group_id::text, ''), COALESCE(user_group_key, ''), model,
|
||||
COALESCE(model_type, ''), COALESCE(requested_model, ''), COALESCE(resolved_model, ''), COALESCE(request_id, ''),
|
||||
COALESCE(conversation_id::text, ''), COALESCE(new_message_count, 0),
|
||||
request, COALESCE(async_mode, false), COALESCE(river_job_id, 0), status, COALESCE(attempt_count, 0),
|
||||
request, COALESCE(async_mode, false), COALESCE(river_job_id, 0), status,
|
||||
COALESCE(queue_key, 'default'), COALESCE(priority, 100), COALESCE(attempt_count, 0),
|
||||
COALESCE(remote_task_id, ''), COALESCE(remote_task_payload, '{}'::jsonb),
|
||||
COALESCE(result, '{}'::jsonb), COALESCE(billings, '[]'::jsonb),
|
||||
COALESCE(usage, '{}'::jsonb), COALESCE(metrics, '{}'::jsonb), COALESCE(billing_summary, '{}'::jsonb),
|
||||
@@ -715,6 +725,11 @@ ORDER BY COALESCE(dynamic_priority, priority) ASC, priority ASC, created_at DESC
|
||||
}
|
||||
|
||||
func (s *Store) CreatePlatform(ctx context.Context, input CreatePlatformInput) (Platform, error) {
|
||||
normalizedPolicy, err := NormalizeAndValidateRateLimitPolicy(input.RateLimitPolicy)
|
||||
if err != nil {
|
||||
return Platform{}, err
|
||||
}
|
||||
input.RateLimitPolicy = normalizedPolicy
|
||||
credentials, _ := json.Marshal(emptyObjectIfNil(input.Credentials))
|
||||
config, _ := json.Marshal(emptyObjectIfNil(input.Config))
|
||||
retryPolicy, _ := json.Marshal(emptyObjectIfNil(input.RetryPolicy))
|
||||
@@ -734,7 +749,7 @@ func (s *Store) CreatePlatform(ctx context.Context, input CreatePlatformInput) (
|
||||
var retryPolicyBytes []byte
|
||||
var rateLimitPolicyBytes []byte
|
||||
var dynamicPriority sql.NullInt64
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
err = s.pool.QueryRow(ctx, `
|
||||
INSERT INTO integration_platforms (
|
||||
provider, platform_key, name, internal_name, base_url, auth_type, credentials, config,
|
||||
default_pricing_mode, default_discount_factor, pricing_rule_set_id,
|
||||
@@ -789,6 +804,11 @@ RETURNING id::text, provider, platform_key, name, COALESCE(internal_name, ''), C
|
||||
}
|
||||
|
||||
func (s *Store) UpdatePlatform(ctx context.Context, id string, input CreatePlatformInput) (Platform, error) {
|
||||
normalizedPolicy, err := NormalizeAndValidateRateLimitPolicy(input.RateLimitPolicy)
|
||||
if err != nil {
|
||||
return Platform{}, err
|
||||
}
|
||||
input.RateLimitPolicy = normalizedPolicy
|
||||
var credentials any
|
||||
if input.Credentials != nil {
|
||||
credentialsBytes, _ := json.Marshal(emptyObjectIfNil(input.Credentials))
|
||||
@@ -812,7 +832,7 @@ func (s *Store) UpdatePlatform(ctx context.Context, id string, input CreatePlatf
|
||||
var retryPolicyBytes []byte
|
||||
var rateLimitPolicyBytes []byte
|
||||
var dynamicPriority sql.NullInt64
|
||||
err := s.pool.QueryRow(ctx, `
|
||||
err = s.pool.QueryRow(ctx, `
|
||||
UPDATE integration_platforms
|
||||
SET provider = $2,
|
||||
platform_key = COALESCE(NULLIF($3, ''), platform_key),
|
||||
@@ -2138,6 +2158,8 @@ func scanGatewayTask(scanner taskScanner) (GatewayTask, error) {
|
||||
&task.AsyncMode,
|
||||
&task.RiverJobID,
|
||||
&task.Status,
|
||||
&task.QueueKey,
|
||||
&task.Priority,
|
||||
&task.AttemptCount,
|
||||
&task.RemoteTaskID,
|
||||
&remoteTaskPayloadBytes,
|
||||
|
||||
Reference in New Issue
Block a user