1
1
//! Load Balancer chooses server by statistic latency data collected from active probing
2
2
3
3
use std:: {
4
+ cmp,
4
5
fmt:: { self , Debug , Display } ,
5
6
io,
6
7
iter:: Iterator ,
@@ -29,6 +30,7 @@ use shadowsocks::{
29
30
use spin:: Mutex as SpinMutex ;
30
31
use tokio:: {
31
32
io:: { AsyncBufReadExt , AsyncWriteExt , BufReader } ,
33
+ sync:: Notify ,
32
34
task:: JoinHandle ,
33
35
time,
34
36
} ;
@@ -208,6 +210,7 @@ struct PingBalancerContext {
208
210
max_server_rtt : Duration ,
209
211
check_interval : Duration ,
210
212
check_best_interval : Option < Duration > ,
213
+ best_task_notify : Notify ,
211
214
}
212
215
213
216
impl PingBalancerContext {
@@ -303,6 +306,7 @@ impl PingBalancerContext {
303
306
max_server_rtt,
304
307
check_interval,
305
308
check_best_interval,
309
+ best_task_notify : Notify :: new ( ) ,
306
310
} ;
307
311
308
312
balancer_context. init_score ( ) . await ;
@@ -602,6 +606,27 @@ impl PingBalancerContext {
602
606
}
603
607
604
608
async fn checker_task_all_servers ( & self ) {
609
+ if let Some ( check_best_interval) = self . check_best_interval {
610
+ // Get at least 10 points to get the precise scores
611
+
612
+ let interval = cmp:: min ( check_best_interval, self . check_interval ) ;
613
+
614
+ let mut count = 0 ;
615
+ while count < EXPECTED_CHECK_POINTS_IN_CHECK_WINDOW {
616
+ time:: sleep ( interval) . await ;
617
+
618
+ // Sleep before check.
619
+ // PingBalancer already checked once when constructing
620
+ self . check_once ( false ) . await ;
621
+
622
+ count += 1 ;
623
+ }
624
+
625
+ self . best_task_notify . notify_one ( ) ;
626
+
627
+ trace ! ( "finished initializing server scores" ) ;
628
+ }
629
+
605
630
loop {
606
631
time:: sleep ( self . check_interval ) . await ;
607
632
@@ -612,6 +637,10 @@ impl PingBalancerContext {
612
637
}
613
638
614
639
async fn checker_task_best_server ( & self ) {
640
+ // Wait until checker_task_all_servers notify.
641
+ // Because when server starts, the scores are unstable, so we have to run check_all for multiple times
642
+ self . best_task_notify . notified ( ) . await ;
643
+
615
644
let check_best_interval = self . check_best_interval . unwrap ( ) ;
616
645
617
646
loop {
0 commit comments