@@ -9,7 +9,7 @@ mod usage;
99use crate :: { core:: AppCore , models:: * } ;
1010use std:: {
1111 path:: { Path , PathBuf } ,
12- sync:: atomic:: { AtomicU64 , Ordering } ,
12+ sync:: atomic:: { AtomicBool , AtomicU64 , Ordering } ,
1313 time:: { Duration , Instant } ,
1414} ;
1515use tauri:: {
8080}
8181
8282fn emit_node_test_progress ( app : & tauri:: AppHandle , completed : usize , total : usize ) {
83- let _ = app. emit ( "node-test-progress" , NodeTestProgress { completed, total } ) ;
83+ let _ = app. emit (
84+ "node-test-progress" ,
85+ NodeTestProgress {
86+ completed,
87+ total,
88+ finished : false ,
89+ } ,
90+ ) ;
91+ }
92+
93+ fn emit_node_test_finished ( app : & tauri:: AppHandle ) {
94+ let _ = app. emit (
95+ "node-test-progress" ,
96+ NodeTestProgress {
97+ completed : 0 ,
98+ total : 0 ,
99+ finished : true ,
100+ } ,
101+ ) ;
84102}
85103
86104#[ tauri:: command]
@@ -122,23 +140,18 @@ async fn test_all_nodes(app: tauri::AppHandle) -> CommandResult<Vec<NodeEntry>>
122140 emit_node_test_progress ( & progress_app, completed, total) ;
123141 } )
124142 } )
125- . await ?;
143+ . await ;
144+ emit_node_test_finished ( & app) ;
145+ let result = result?;
126146 refresh_tray_from_core ( & app) ;
127147 Ok ( result)
128148}
129149
130150#[ tauri:: command]
131151async fn refresh_system_nodes ( app : tauri:: AppHandle ) -> CommandResult < bool > {
132- let progress_app = app. clone ( ) ;
133152 let worker_app = app. clone ( ) ;
134- let result = run_node_test ( move || {
135- worker_app
136- . state :: < AppCore > ( )
137- . refresh_system_nodes_with_progress ( |completed, total| {
138- emit_node_test_progress ( & progress_app, completed, total) ;
139- } )
140- } )
141- . await ?;
153+ let result =
154+ run_node_test ( move || worker_app. state :: < AppCore > ( ) . refresh_system_nodes ( ) ) . await ?;
142155 refresh_tray_from_core ( & app) ;
143156 Ok ( result)
144157}
@@ -347,6 +360,7 @@ fn install_tray(app: &tauri::App) -> tauri::Result<()> {
347360 . test_all_nodes_or_join_with_progress ( |completed, total| {
348361 emit_node_test_progress ( & handle, completed, total)
349362 } ) ;
363+ emit_node_test_finished ( & handle) ;
350364 match result {
351365 Ok ( _) => {
352366 if let Ok ( state) = handle. state :: < AppCore > ( ) . snapshot ( ) {
@@ -372,33 +386,45 @@ fn install_tray(app: &tauri::App) -> tauri::Result<()> {
372386fn start_health_monitor ( app : tauri:: AppHandle ) {
373387 tauri:: async_runtime:: spawn ( async move {
374388 let mut last_check = Instant :: now ( ) ;
389+ let mut initial_discovery_pending = true ;
375390 loop {
376391 tokio:: time:: sleep ( Duration :: from_secs ( 60 ) ) . await ;
377- let minutes = app
378- . state :: < AppCore > ( )
392+ let core = app. state :: < AppCore > ( ) ;
393+ let minutes = core
379394 . snapshot ( )
380395 . map ( |state| state. settings . health_check_minutes )
381396 . unwrap_or ( 0 ) ;
382- if minutes == 0 || last_check. elapsed ( ) < Duration :: from_secs ( u64:: from ( minutes) * 60 ) {
397+ let needs_initial_discovery = initial_discovery_pending
398+ && core. needs_background_node_discovery ( ) . unwrap_or ( false ) ;
399+ if !health_check_due ( minutes, last_check. elapsed ( ) , needs_initial_discovery) {
383400 continue ;
384401 }
385- last_check = Instant :: now ( ) ;
386402 let handle = app. clone ( ) ;
387- let _ = tauri:: async_runtime:: spawn_blocking ( move || {
388- if handle
403+ let succeeded = tauri:: async_runtime:: spawn_blocking ( move || {
404+ let started = AtomicBool :: new ( false ) ;
405+ let result = handle
389406 . state :: < AppCore > ( )
390- . test_all_nodes_with_progress ( |completed, total| {
407+ . test_background_nodes_with_progress ( |completed, total| {
408+ started. store ( true , Ordering :: Relaxed ) ;
391409 emit_node_test_progress ( & handle, completed, total) ;
392- } )
393- . is_ok ( )
394- {
410+ } ) ;
411+ if started. load ( Ordering :: Relaxed ) {
412+ emit_node_test_finished ( & handle) ;
413+ }
414+ if result. is_ok ( ) {
395415 if let Ok ( state) = handle. state :: < AppCore > ( ) . snapshot ( ) {
396416 refresh_tray ( & handle, & state) ;
397417 let _ = handle. emit ( "snapshot-updated" , state) ;
398418 }
399419 }
420+ result. is_ok ( )
400421 } )
401- . await ;
422+ . await
423+ . unwrap_or ( false ) ;
424+ if succeeded {
425+ last_check = Instant :: now ( ) ;
426+ initial_discovery_pending = false ;
427+ }
402428 }
403429 } ) ;
404430}
@@ -409,9 +435,7 @@ fn start_system_node_monitor(app: tauri::AppHandle) {
409435 let handle = app. clone ( ) ;
410436 let _ = tauri:: async_runtime:: spawn_blocking ( move || {
411437 let core = handle. state :: < AppCore > ( ) ;
412- if let Err ( error) = core. refresh_system_nodes_with_progress ( |completed, total| {
413- emit_node_test_progress ( & handle, completed, total) ;
414- } ) {
438+ if let Err ( error) = core. refresh_system_nodes ( ) {
415439 core. system_node_refresh_failed ( & error) ;
416440 }
417441 if let Ok ( state) = core. snapshot ( ) {
@@ -425,6 +449,11 @@ fn start_system_node_monitor(app: tauri::AppHandle) {
425449 } ) ;
426450}
427451
452+ fn health_check_due ( minutes : u32 , elapsed : Duration , needs_initial_discovery : bool ) -> bool {
453+ minutes != 0
454+ && ( needs_initial_discovery || elapsed >= Duration :: from_secs ( u64:: from ( minutes) * 60 ) )
455+ }
456+
428457pub fn run ( ) {
429458 let autostart = tauri_plugin_autostart:: Builder :: new ( ) ;
430459 #[ cfg( target_os = "macos" ) ]
@@ -488,8 +517,9 @@ pub fn run() {
488517
489518#[ cfg( test) ]
490519mod tests {
491- use super :: { run_node_test, tray_labels} ;
520+ use super :: { health_check_due , run_node_test, tray_labels} ;
492521 use crate :: models:: { HealthSummary , NodeDefinition , NodeEntry , Settings } ;
522+ use std:: time:: Duration ;
493523
494524 #[ test]
495525 fn node_tests_run_off_the_calling_thread ( ) {
@@ -529,4 +559,20 @@ mod tests {
529559 ( "当前线路:GitHub 直连" . into( ) , "开启加速" )
530560 ) ;
531561 }
562+
563+ #[ test]
564+ fn health_check_schedule_honors_interval_and_disabled_setting ( ) {
565+ assert ! ( !health_check_due( 0 , Duration :: from_secs( 86_400 ) , true ) ) ;
566+ assert ! ( !health_check_due(
567+ 24 * 60 ,
568+ Duration :: from_secs( 6 * 60 * 60 ) ,
569+ false
570+ ) ) ;
571+ assert ! ( health_check_due(
572+ 8 * 60 ,
573+ Duration :: from_secs( 8 * 60 * 60 ) ,
574+ false
575+ ) ) ;
576+ assert ! ( health_check_due( 24 * 60 , Duration :: from_secs( 60 ) , true ) ) ;
577+ }
532578}
0 commit comments