feat(proxy): implement independent failover queue management

Add a new failover queue system that operates independently from provider
sortIndex, allowing users to configure failover order per app type.

Backend changes:
- Add failover_queue table to schema.rs for persistent storage
- Create dao/failover.rs with CRUD operations for queue management
- Add Tauri commands for queue operations (get, add, remove, reorder, toggle)
- Refactor provider_router.rs select_providers() to use failover queue:
  - Current provider always takes first priority
  - Queue providers ordered by queue_order as fallback
  - Only providers with open circuit breakers are included

Frontend changes:
- Add FailoverQueueItem type to proxy.ts
- Extend failover.ts API with queue management methods
- Add React Query hooks for queue data fetching and mutations
- Create FailoverQueueManager component with drag-and-drop reordering
- Integrate queue management into SettingsPage under "Auto Failover"
- Add i18n translations for zh and en locales
This commit is contained in:
Jason
2025-12-12 16:13:07 +08:00
parent c42a0dccaf
commit 5d424b1383
15 changed files with 1198 additions and 47 deletions
+45
View File
@@ -840,5 +840,50 @@
},
"agents": {
"title": "Agents"
},
"proxy": {
"failoverQueue": {
"title": "Failover Queue",
"description": "Manage failover order for each app's providers",
"info": "The current active provider always takes priority. When requests fail, the system will try other providers in queue order.",
"selectProvider": "Select a provider to add to queue",
"noAvailableProviders": "No providers available to add",
"empty": "Failover queue is empty. Add providers to enable automatic failover.",
"dragHint": "Drag providers to adjust failover order. Lower numbers have higher priority.",
"toggleEnabled": "Enable/Disable",
"addSuccess": "Added to failover queue",
"addFailed": "Failed to add",
"removeSuccess": "Removed from failover queue",
"removeFailed": "Failed to remove",
"reorderSuccess": "Queue order updated",
"reorderFailed": "Failed to update order",
"toggleFailed": "Failed to update status"
},
"autoFailover": {
"info": "When multiple proxy targets are enabled, the system will try them in priority order. When a provider fails consecutively reaching the threshold, the circuit breaker will open and skip that provider.",
"configSaved": "Auto failover config saved",
"configSaveFailed": "Failed to save",
"retrySettings": "Retry & Timeout Settings",
"failureThreshold": "Failure Threshold",
"failureThresholdHint": "Open circuit breaker after this many consecutive failures (recommended: 3-10)",
"timeout": "Recovery Wait Time (seconds)",
"timeoutHint": "Wait this long before trying to recover after circuit opens (recommended: 30-120)",
"circuitBreakerSettings": "Circuit Breaker Advanced Settings",
"successThreshold": "Recovery Success Threshold",
"successThresholdHint": "Close circuit breaker after this many successes in half-open state",
"errorRate": "Error Rate Threshold (%)",
"errorRateHint": "Open circuit breaker when error rate exceeds this value",
"minRequests": "Minimum Requests",
"minRequestsHint": "Minimum requests before calculating error rate",
"explanationTitle": "How It Works",
"failureThresholdLabel": "Failure Threshold",
"failureThresholdExplain": "Circuit breaker opens after this many consecutive failures, making the provider temporarily unavailable",
"timeoutLabel": "Recovery Wait Time",
"timeoutExplain": "After circuit opens, wait this long before trying half-open state",
"successThresholdLabel": "Recovery Success Threshold",
"successThresholdExplain": "In half-open state, close circuit breaker after this many successes, making provider available again",
"errorRateLabel": "Error Rate Threshold",
"errorRateExplain": "Open circuit breaker when error rate exceeds this value, even if failure threshold not reached"
}
}
}
+45
View File
@@ -840,5 +840,50 @@
},
"agents": {
"title": "智能体"
},
"proxy": {
"failoverQueue": {
"title": "故障转移队列",
"description": "管理各应用的供应商故障转移顺序",
"info": "当前激活的供应商始终优先。当请求失败时,系统会按队列顺序依次尝试其他供应商。",
"selectProvider": "选择供应商添加到队列",
"noAvailableProviders": "没有可添加的供应商",
"empty": "故障转移队列为空。添加供应商以启用自动故障转移。",
"dragHint": "拖拽供应商可调整故障转移顺序,序号越小优先级越高。",
"toggleEnabled": "启用/禁用",
"addSuccess": "已添加到故障转移队列",
"addFailed": "添加失败",
"removeSuccess": "已从故障转移队列移除",
"removeFailed": "移除失败",
"reorderSuccess": "队列顺序已更新",
"reorderFailed": "更新顺序失败",
"toggleFailed": "状态更新失败"
},
"autoFailover": {
"info": "当启用多个代理目标时,系统会按优先级顺序依次尝试。当某个供应商连续失败达到阈值时,熔断器会自动打开,跳过该供应商。",
"configSaved": "自动故障转移配置已保存",
"configSaveFailed": "保存失败",
"retrySettings": "重试与超时设置",
"failureThreshold": "失败阈值",
"failureThresholdHint": "连续失败多少次后打开熔断器(建议: 3-10)",
"timeout": "恢复等待时间(秒)",
"timeoutHint": "熔断器打开后,等待多久后尝试恢复(建议: 30-120)",
"circuitBreakerSettings": "熔断器高级设置",
"successThreshold": "恢复成功阈值",
"successThresholdHint": "半开状态下成功多少次后关闭熔断器",
"errorRate": "错误率阈值 (%)",
"errorRateHint": "错误率超过此值时打开熔断器",
"minRequests": "最小请求数",
"minRequestsHint": "计算错误率前的最小请求数",
"explanationTitle": "工作原理",
"failureThresholdLabel": "失败阈值",
"failureThresholdExplain": "连续失败达到此次数时,熔断器打开,该供应商暂时不可用",
"timeoutLabel": "恢复等待时间",
"timeoutExplain": "熔断器打开后,等待此时间后尝试半开状态",
"successThresholdLabel": "恢复成功阈值",
"successThresholdExplain": "半开状态下,成功达到此次数时关闭熔断器,供应商恢复可用",
"errorRateLabel": "错误率阈值",
"errorRateExplain": "错误率超过此值时,即使未达到失败阈值也会打开熔断器"
}
}
}