feat: add runner failover rules and cache affinity

This commit is contained in:
2026-06-28 20:50:23 +08:00
parent 41bb3a6525
commit 0e675e259c
31 changed files with 2939 additions and 470 deletions
+56 -5
View File
@@ -129,6 +129,18 @@ WHERE id = $1::uuid`, platformID)
return err
}
func (s *Store) DisableCandidatePlatformModel(ctx context.Context, platformModelID string) error {
if strings.TrimSpace(platformModelID) == "" {
return nil
}
_, err := s.pool.Exec(ctx, `
UPDATE platform_models
SET enabled = false,
updated_at = now()
WHERE id = $1::uuid`, platformModelID)
return err
}
func (s *Store) CooldownCandidatePlatform(ctx context.Context, platformID string, cooldownSeconds int) error {
if strings.TrimSpace(platformID) == "" {
return nil
@@ -160,9 +172,16 @@ WHERE id = $1::uuid`, platformModelID, cooldownSeconds)
}
func (s *Store) DemoteCandidatePlatformPriority(ctx context.Context, platformID string, platformModelID string, requestedModel string, modelType string) (int, error) {
return s.DemoteCandidatePlatformPriorityBySteps(ctx, platformID, platformModelID, requestedModel, modelType, 99)
}
func (s *Store) DemoteCandidatePlatformPriorityBySteps(ctx context.Context, platformID string, platformModelID string, requestedModel string, modelType string, demoteSteps int) (int, error) {
if strings.TrimSpace(platformID) == "" || strings.TrimSpace(platformModelID) == "" || strings.TrimSpace(requestedModel) == "" {
return 0, nil
}
if demoteSteps <= 0 {
demoteSteps = 1
}
var dynamicPriority int
err := s.pool.QueryRow(ctx, `
WITH current_model AS (
@@ -171,10 +190,13 @@ func (s *Store) DemoteCandidatePlatformPriority(ctx context.Context, platformID
WHERE id = $2::uuid
AND platform_id = $1::uuid
),
peer_priority AS (
SELECT MAX(COALESCE(peer.dynamic_priority, peer.priority)) AS max_priority
eligible_raw AS (
SELECT peer.id AS platform_id,
peer.priority,
COALESCE(peer.dynamic_priority, peer.priority) AS effective_priority,
peer.created_at
FROM current_model current
JOIN platform_models peer_model ON peer_model.platform_id <> current.platform_id
JOIN platform_models peer_model ON TRUE
JOIN integration_platforms peer ON peer.id = peer_model.platform_id
LEFT JOIN base_model_catalog peer_base ON peer_base.id = peer_model.base_model_id
WHERE peer.status = 'enabled'
@@ -194,14 +216,43 @@ func (s *Store) DemoteCandidatePlatformPriority(ctx context.Context, platformID
)
)
)
),
eligible AS (
SELECT DISTINCT ON (platform_id) platform_id, priority, effective_priority, created_at
FROM eligible_raw
ORDER BY platform_id, effective_priority ASC, priority ASC, created_at ASC
),
ordered AS (
SELECT platform_id, effective_priority,
row_number() OVER (ORDER BY effective_priority ASC, priority ASC, created_at ASC, platform_id ASC) AS rn
FROM eligible
),
current_position AS (
SELECT rn, effective_priority
FROM ordered
WHERE platform_id = $1::uuid
),
next_position AS (
SELECT ordered.effective_priority
FROM ordered, current_position
WHERE ordered.rn >= current_position.rn + $5::int
ORDER BY ordered.rn ASC
LIMIT 1
),
target_priority AS (
SELECT COALESCE(
(SELECT effective_priority FROM next_position),
(SELECT MAX(effective_priority) FROM ordered),
(SELECT effective_priority + $5::int FROM current_position)
) AS value
)
UPDATE integration_platforms target
SET dynamic_priority = COALESCE((SELECT max_priority FROM peer_priority), target.priority) + 1,
SET dynamic_priority = COALESCE((SELECT value FROM target_priority), target.priority) + 1,
updated_at = now()
WHERE target.id = $1::uuid
AND target.deleted_at IS NULL
AND EXISTS (SELECT 1 FROM current_model)
RETURNING dynamic_priority`, platformID, platformModelID, requestedModel, modelType).Scan(&dynamicPriority)
RETURNING dynamic_priority`, platformID, platformModelID, requestedModel, modelType, demoteSteps).Scan(&dynamicPriority)
return dynamicPriority, err
}