From 762f9a96fdc194338eb28f08e0135c3933e84f58 Mon Sep 17 00:00:00 2001 From: Tunglies <77394545+Tunglies@users.noreply.github.com> Date: Fri, 24 Apr 2026 20:20:50 +0800 Subject: [PATCH] refactor media unlock task collection --- crates/clash-verge-draft/bench/benche_me.rs | 6 +- src-tauri/src/cmd/media_unlock_checker/mod.rs | 181 ++++++------------ .../src/cmd/media_unlock_checker/netflix.rs | 10 +- src-tauri/src/utils/init.rs | 3 - 4 files changed, 62 insertions(+), 138 deletions(-) diff --git a/crates/clash-verge-draft/bench/benche_me.rs b/crates/clash-verge-draft/bench/benche_me.rs index 1f7daa165..aedcdc606 100644 --- a/crates/clash-verge-draft/bench/benche_me.rs +++ b/crates/clash-verge-draft/bench/benche_me.rs @@ -1,6 +1,5 @@ use criterion::{Criterion, criterion_group, criterion_main}; use std::hint::black_box; -use std::process; use tokio::runtime::Runtime; use clash_verge_draft::Draft; @@ -20,10 +19,7 @@ fn make_draft() -> Draft { } pub fn bench_draft(c: &mut Criterion) { - let rt = Runtime::new().unwrap_or_else(|e| { - eprintln!("Tokio runtime init failed: {e}"); - process::exit(1); - }); + let rt = Runtime::new().unwrap_or_else(|e| panic!("Tokio runtime init failed: {e}")); let mut group = c.benchmark_group("draft"); group.sample_size(100); diff --git a/src-tauri/src/cmd/media_unlock_checker/mod.rs b/src-tauri/src/cmd/media_unlock_checker/mod.rs index 015078b0d..42dd252d9 100644 --- a/src-tauri/src/cmd/media_unlock_checker/mod.rs +++ b/src-tauri/src/cmd/media_unlock_checker/mod.rs @@ -1,8 +1,8 @@ -use std::sync::Arc; +use std::{future::Future, sync::Arc}; use reqwest::Client; use tauri::command; -use tokio::{sync::Mutex, task::JoinSet}; +use tokio::task::JoinSet; use clash_verge_logging::{Type, logging}; @@ -34,6 +34,20 @@ use spotify::check_spotify; use tiktok::check_tiktok; use youtube::check_youtube_premium; +type UnlockResults = Vec; + +fn spawn_unlock_check(tasks: &mut JoinSet, client: Arc, check: F) +where + F: FnOnce(Arc) -> Fut + Send + 'static, + Fut: Future + Send + 'static, +{ + tasks.spawn(async move { check(client).await }); +} + +fn single_result(item: UnlockItem) -> UnlockResults { + vec![item] +} + #[command] pub async fn get_unlock_items() -> Result, String> { Ok(types::default_unlock_items()) @@ -54,136 +68,53 @@ pub async fn check_media_unlock() -> Result, String> { Err(e) => return Err(format!("创建HTTP客户端失败: {e}")), }; - let results = Arc::new(Mutex::new(Vec::new())); let mut tasks = JoinSet::new(); let client_arc = Arc::new(client); - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_bilibili_china_mainland(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_bilibili_hk_mc_tw(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let chatgpt_results = check_chatgpt_combined(&client).await; - let mut results = results.lock().await; - results.extend(chatgpt_results); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_claude(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_gemini(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_youtube_premium(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_bahamut_anime(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_netflix(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_disney_plus(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_spotify(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_tiktok(&client).await; - results.lock().await.push(result); - }); - } - - { - let client = Arc::clone(&client_arc); - let results = Arc::clone(&results); - tasks.spawn(async move { - let result = check_prime_video(&client).await; - results.lock().await.push(result); - }); - } + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_bilibili_china_mainland(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_bilibili_hk_mc_tw(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + check_chatgpt_combined(&client).await + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_claude(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_gemini(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_youtube_premium(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_bahamut_anime(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_netflix(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_disney_plus(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_spotify(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_tiktok(&client).await) + }); + spawn_unlock_check(&mut tasks, Arc::clone(&client_arc), |client| async move { + single_result(check_prime_video(&client).await) + }); + let mut results = Vec::new(); while let Some(res) = tasks.join_next().await { - if let Err(e) = res { - eprintln!("任务执行失败: {e}"); + match res { + Ok(items) => results.extend(items), + Err(e) => logging!(error, Type::Network, "任务执行失败: {e}"), } } - let results = match Arc::try_unwrap(results) { - Ok(mutex) => mutex.into_inner(), - Err(_) => { - logging!( - error, - Type::Network, - "Failed to unwrap results Arc, references still exist" - ); - return Err("Failed to collect results".to_string()); - } - }; - Ok(results) } diff --git a/src-tauri/src/cmd/media_unlock_checker/netflix.rs b/src-tauri/src/cmd/media_unlock_checker/netflix.rs index f4aefccbd..229148c86 100644 --- a/src-tauri/src/cmd/media_unlock_checker/netflix.rs +++ b/src-tauri/src/cmd/media_unlock_checker/netflix.rs @@ -22,7 +22,7 @@ pub(super) async fn check_netflix(client: &Client) -> UnlockItem { .await; if let Err(e) = &result1 { - eprintln!("Netflix请求错误: {e}"); + logging!(error, Type::Network, "Netflix请求错误: {e}"); return UnlockItem { name: "Netflix".to_string(), status: "Failed".to_string(), @@ -38,7 +38,7 @@ pub(super) async fn check_netflix(client: &Client) -> UnlockItem { .await; if let Err(e) = &result2 { - eprintln!("Netflix请求错误: {e}"); + logging!(error, Type::Network, "Netflix请求错误: {e}"); return UnlockItem { name: "Netflix".to_string(), status: "Failed".to_string(), @@ -125,7 +125,7 @@ pub(super) async fn check_netflix(client: &Client) -> UnlockItem { } } Err(e) => { - eprintln!("获取Netflix区域信息失败: {e}"); + logging!(error, Type::Network, "获取Netflix区域信息失败: {e}"); UnlockItem { name: "Netflix".to_string(), status: "Yes (但无法获取区域)".to_string(), @@ -182,7 +182,7 @@ async fn check_netflix_cdn(client: &Client) -> UnlockItem { } } Err(e) => { - eprintln!("解析Fast.com API响应失败: {e}"); + logging!(error, Type::Network, "解析Fast.com API响应失败: {e}"); UnlockItem { name: "Netflix".to_string(), status: "Failed (解析错误)".to_string(), @@ -193,7 +193,7 @@ async fn check_netflix_cdn(client: &Client) -> UnlockItem { } } Err(e) => { - eprintln!("Fast.com API请求失败: {e}"); + logging!(error, Type::Network, "Fast.com API请求失败: {e}"); UnlockItem { name: "Netflix".to_string(), status: "Failed (CDN API)".to_string(), diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs index 43b61c8f2..d4fbdcdac 100644 --- a/src-tauri/src/utils/init.rs +++ b/src-tauri/src/utils/init.rs @@ -294,9 +294,6 @@ pub async fn init_config() -> Result<()> { // let _ = dirs::init_portable_flag(); // We do not need init_log here anymore due to resolve will to the things - // if let Err(e) = init_log().await { - // eprintln!("Failed to initialize logging: {}", e); - // } ensure_directories().await?;