refactor(runner): 收敛上游失败决策与轮转策略
将同平台重试、跨平台动作、健康副作用和冷却排队统一到单一失败决策,避免旧降级策略与 failover 重复执行。\n\n增加事务级单源保护、候选实时刷新、冷却错误契约、管理接口严格校验及兼容策略只读展示。\n\n验证:真实 Gateway HTTP/PostgreSQL 接受测试 10 项通过;go test ./...、pnpm openapi、pnpm lint、pnpm test、pnpm build 均通过。
This commit is contained in:
@@ -470,6 +470,13 @@ func (s *Store) RequeueTask(ctx context.Context, taskID string, executionToken s
|
||||
delay = 10 * time.Minute
|
||||
}
|
||||
nextRunAt := time.Now().Add(delay)
|
||||
return s.RequeueTaskUntil(ctx, taskID, executionToken, nextRunAt, queueKey)
|
||||
}
|
||||
|
||||
func (s *Store) RequeueTaskUntil(ctx context.Context, taskID string, executionToken string, nextRunAt time.Time, queueKey string) (GatewayTask, error) {
|
||||
if nextRunAt.Before(time.Now().Add(time.Second)) {
|
||||
nextRunAt = time.Now().Add(time.Second)
|
||||
}
|
||||
return scanGatewayTask(s.pool.QueryRow(ctx, `
|
||||
UPDATE gateway_tasks
|
||||
SET status = 'queued',
|
||||
@@ -820,6 +827,29 @@ ORDER BY COALESCE(attempt_no, 0), created_at`, taskID)
|
||||
}
|
||||
|
||||
func (s *Store) AppendTaskAttemptTrace(ctx context.Context, taskID string, attemptNo int, entry map[string]any) error {
|
||||
if strings.TrimSpace(taskID) == "" || attemptNo <= 0 || len(entry) == 0 {
|
||||
return nil
|
||||
}
|
||||
encoded, err := json.Marshal(entry)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result, err := s.pool.Exec(ctx, `
|
||||
UPDATE gateway_task_attempts
|
||||
SET metrics = jsonb_set(
|
||||
COALESCE(metrics, '{}'::jsonb),
|
||||
'{trace}',
|
||||
COALESCE(metrics->'trace', '[]'::jsonb) || jsonb_build_array($3::jsonb),
|
||||
true
|
||||
)
|
||||
WHERE task_id = $1::uuid
|
||||
AND attempt_no = $2::int`, taskID, attemptNo, encoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if result.RowsAffected() == 0 {
|
||||
return pgx.ErrNoRows
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user