mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-25 13:45:03 +08:00
e6654bd7f9
- Remove `is_proxy_target` field from Provider struct (Rust & TypeScript) - Remove related DAO methods: get_proxy_target_provider, set_proxy_target - Remove deprecated Tauri commands: get_proxy_targets, set_proxy_target - Add `is_available()` method to CircuitBreaker for availability checks without consuming HalfOpen probe permits (used in select_providers) - Keep `allow_request()` for actual request gating with permit tracking - Update stream_check to use failover_queue instead of is_proxy_target - Clean up commented-out reset circuit breaker button in ProviderActions - Remove unused useProxyTargets and useSetProxyTarget hooks
109 lines
3.2 KiB
Rust
109 lines
3.2 KiB
Rust
//! 流式健康检查命令
|
|
|
|
use crate::app_config::AppType;
|
|
use crate::error::AppError;
|
|
use crate::services::stream_check::{
|
|
HealthStatus, StreamCheckConfig, StreamCheckResult, StreamCheckService,
|
|
};
|
|
use crate::store::AppState;
|
|
use std::collections::HashSet;
|
|
use tauri::State;
|
|
|
|
/// 流式健康检查(单个供应商)
|
|
#[tauri::command]
|
|
pub async fn stream_check_provider(
|
|
state: State<'_, AppState>,
|
|
app_type: AppType,
|
|
provider_id: String,
|
|
) -> Result<StreamCheckResult, AppError> {
|
|
let config = state.db.get_stream_check_config()?;
|
|
|
|
let providers = state.db.get_all_providers(app_type.as_str())?;
|
|
let provider = providers
|
|
.get(&provider_id)
|
|
.ok_or_else(|| AppError::Message(format!("供应商 {provider_id} 不存在")))?;
|
|
|
|
let result = StreamCheckService::check_with_retry(&app_type, provider, &config).await?;
|
|
|
|
// 记录日志
|
|
let _ =
|
|
state
|
|
.db
|
|
.save_stream_check_log(&provider_id, &provider.name, app_type.as_str(), &result);
|
|
|
|
Ok(result)
|
|
}
|
|
|
|
/// 批量流式健康检查
|
|
#[tauri::command]
|
|
pub async fn stream_check_all_providers(
|
|
state: State<'_, AppState>,
|
|
app_type: AppType,
|
|
proxy_targets_only: bool,
|
|
) -> Result<Vec<(String, StreamCheckResult)>, AppError> {
|
|
let config = state.db.get_stream_check_config()?;
|
|
let providers = state.db.get_all_providers(app_type.as_str())?;
|
|
|
|
let mut results = Vec::new();
|
|
let allowed_ids: Option<HashSet<String>> = if proxy_targets_only {
|
|
let mut ids = HashSet::new();
|
|
if let Ok(Some(current_id)) = state.db.get_current_provider(app_type.as_str()) {
|
|
ids.insert(current_id);
|
|
}
|
|
if let Ok(queue) = state.db.get_failover_queue(app_type.as_str()) {
|
|
for item in queue {
|
|
if item.enabled {
|
|
ids.insert(item.provider_id);
|
|
}
|
|
}
|
|
}
|
|
Some(ids)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
for (id, provider) in providers {
|
|
if let Some(ids) = &allowed_ids {
|
|
if !ids.contains(&id) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
let result = StreamCheckService::check_with_retry(&app_type, &provider, &config)
|
|
.await
|
|
.unwrap_or_else(|e| StreamCheckResult {
|
|
status: HealthStatus::Failed,
|
|
success: false,
|
|
message: e.to_string(),
|
|
response_time_ms: None,
|
|
http_status: None,
|
|
model_used: String::new(),
|
|
tested_at: chrono::Utc::now().timestamp(),
|
|
retry_count: 0,
|
|
});
|
|
|
|
let _ = state
|
|
.db
|
|
.save_stream_check_log(&id, &provider.name, app_type.as_str(), &result);
|
|
|
|
results.push((id, result));
|
|
}
|
|
|
|
Ok(results)
|
|
}
|
|
|
|
/// 获取流式检查配置
|
|
#[tauri::command]
|
|
pub fn get_stream_check_config(state: State<'_, AppState>) -> Result<StreamCheckConfig, AppError> {
|
|
state.db.get_stream_check_config()
|
|
}
|
|
|
|
/// 保存流式检查配置
|
|
#[tauri::command]
|
|
pub fn save_stream_check_config(
|
|
state: State<'_, AppState>,
|
|
config: StreamCheckConfig,
|
|
) -> Result<(), AppError> {
|
|
state.db.save_stream_check_config(&config)
|
|
}
|