@@ -3,7 +3,7 @@ use actix_web::http::header::{HeaderValue, CONTENT_TYPE};
3
3
use actix_web:: { HttpRequest , HttpResponse } ;
4
4
use bytes:: Bytes ;
5
5
use futures_util:: { StreamExt , TryStreamExt } ;
6
- use log:: { debug, info, warn} ;
6
+ use log:: { debug, error , info, warn} ;
7
7
use std:: collections:: HashMap ;
8
8
use std:: fmt:: Debug ;
9
9
use std:: sync:: atomic:: AtomicUsize ;
@@ -17,9 +17,11 @@ pub enum Router {
17
17
RoundRobin {
18
18
worker_urls : Arc < RwLock < Vec < String > > > ,
19
19
current_index : AtomicUsize ,
20
+ timeout_secs : u64 ,
20
21
} ,
21
22
Random {
22
23
worker_urls : Arc < RwLock < Vec < String > > > ,
24
+ timeout_secs : u64 ,
23
25
} ,
24
26
CacheAware {
25
27
/*
@@ -89,43 +91,59 @@ pub enum Router {
89
91
cache_threshold : f32 ,
90
92
balance_abs_threshold : usize ,
91
93
balance_rel_threshold : f32 ,
94
+ timeout_secs : u64 ,
92
95
_eviction_thread : Option < thread:: JoinHandle < ( ) > > ,
93
96
} ,
94
97
}
95
98
96
99
#[ derive( Debug , Clone ) ]
97
100
pub enum PolicyConfig {
98
- RandomConfig ,
99
- RoundRobinConfig ,
101
+ RandomConfig {
102
+ timeout_secs : u64 ,
103
+ } ,
104
+ RoundRobinConfig {
105
+ timeout_secs : u64 ,
106
+ } ,
100
107
CacheAwareConfig {
101
108
cache_threshold : f32 ,
102
109
balance_abs_threshold : usize ,
103
110
balance_rel_threshold : f32 ,
104
111
eviction_interval_secs : u64 ,
105
112
max_tree_size : usize ,
113
+ timeout_secs : u64 ,
106
114
} ,
107
115
}
108
116
109
117
impl Router {
110
118
pub fn new ( worker_urls : Vec < String > , policy_config : PolicyConfig ) -> Result < Self , String > {
119
+ // Get timeout from policy config
120
+ let timeout_secs = match & policy_config {
121
+ PolicyConfig :: RandomConfig { timeout_secs } => * timeout_secs,
122
+ PolicyConfig :: RoundRobinConfig { timeout_secs } => * timeout_secs,
123
+ PolicyConfig :: CacheAwareConfig { timeout_secs, .. } => * timeout_secs,
124
+ } ;
125
+
111
126
// Wait until all workers are healthy
112
- Self :: wait_for_healthy_workers ( & worker_urls, 300 , 10 ) ?;
127
+ Self :: wait_for_healthy_workers ( & worker_urls, timeout_secs , 10 ) ?;
113
128
114
129
// Create router based on policy...
115
130
Ok ( match policy_config {
116
- PolicyConfig :: RandomConfig => Router :: Random {
131
+ PolicyConfig :: RandomConfig { timeout_secs } => Router :: Random {
117
132
worker_urls : Arc :: new ( RwLock :: new ( worker_urls) ) ,
133
+ timeout_secs,
118
134
} ,
119
- PolicyConfig :: RoundRobinConfig => Router :: RoundRobin {
135
+ PolicyConfig :: RoundRobinConfig { timeout_secs } => Router :: RoundRobin {
120
136
worker_urls : Arc :: new ( RwLock :: new ( worker_urls) ) ,
121
137
current_index : std:: sync:: atomic:: AtomicUsize :: new ( 0 ) ,
138
+ timeout_secs,
122
139
} ,
123
140
PolicyConfig :: CacheAwareConfig {
124
141
cache_threshold,
125
142
balance_abs_threshold,
126
143
balance_rel_threshold,
127
144
eviction_interval_secs,
128
145
max_tree_size,
146
+ timeout_secs,
129
147
} => {
130
148
let mut running_queue = HashMap :: new ( ) ;
131
149
for url in & worker_urls {
@@ -176,6 +194,7 @@ impl Router {
176
194
cache_threshold,
177
195
balance_abs_threshold,
178
196
balance_rel_threshold,
197
+ timeout_secs,
179
198
_eviction_thread : Some ( eviction_thread) ,
180
199
}
181
200
}
@@ -192,6 +211,10 @@ impl Router {
192
211
193
212
loop {
194
213
if start_time. elapsed ( ) > Duration :: from_secs ( timeout_secs) {
214
+ error ! (
215
+ "Timeout {}s waiting for workers to become healthy" ,
216
+ timeout_secs
217
+ ) ;
195
218
return Err ( format ! (
196
219
"Timeout {}s waiting for workers to become healthy" ,
197
220
timeout_secs
@@ -238,7 +261,7 @@ impl Router {
238
261
fn select_first_worker ( & self ) -> Result < String , String > {
239
262
match self {
240
263
Router :: RoundRobin { worker_urls, .. }
241
- | Router :: Random { worker_urls }
264
+ | Router :: Random { worker_urls, .. }
242
265
| Router :: CacheAware { worker_urls, .. } => {
243
266
if worker_urls. read ( ) . unwrap ( ) . is_empty ( ) {
244
267
Err ( "No workers are available" . to_string ( ) )
@@ -349,6 +372,7 @@ impl Router {
349
372
Router :: RoundRobin {
350
373
worker_urls,
351
374
current_index,
375
+ ..
352
376
} => {
353
377
let idx = current_index
354
378
. fetch_update (
@@ -360,7 +384,7 @@ impl Router {
360
384
worker_urls. read ( ) . unwrap ( ) [ idx] . clone ( )
361
385
}
362
386
363
- Router :: Random { worker_urls } => worker_urls. read ( ) . unwrap ( )
387
+ Router :: Random { worker_urls, .. } => worker_urls. read ( ) . unwrap ( )
364
388
[ rand:: random :: < usize > ( ) % worker_urls. read ( ) . unwrap ( ) . len ( ) ]
365
389
. clone ( ) ,
366
390
@@ -571,13 +595,21 @@ impl Router {
571
595
572
596
pub async fn add_worker ( & self , worker_url : & str ) -> Result < String , String > {
573
597
let interval_secs = 10 ; // check every 10 seconds
574
- let timeout_secs = 300 ; // 5 minutes
598
+ let timeout_secs = match self {
599
+ Router :: Random { timeout_secs, .. } => * timeout_secs,
600
+ Router :: RoundRobin { timeout_secs, .. } => * timeout_secs,
601
+ Router :: CacheAware { timeout_secs, .. } => * timeout_secs,
602
+ } ;
575
603
576
604
let start_time = std:: time:: Instant :: now ( ) ;
577
605
let client = reqwest:: Client :: new ( ) ;
578
606
579
607
loop {
580
608
if start_time. elapsed ( ) > Duration :: from_secs ( timeout_secs) {
609
+ error ! (
610
+ "Timeout {}s waiting for worker {} to become healthy" ,
611
+ timeout_secs, worker_url
612
+ ) ;
581
613
return Err ( format ! (
582
614
"Timeout {}s waiting for worker {} to become healthy" ,
583
615
timeout_secs, worker_url
@@ -589,7 +621,7 @@ impl Router {
589
621
if res. status ( ) . is_success ( ) {
590
622
match self {
591
623
Router :: RoundRobin { worker_urls, .. }
592
- | Router :: Random { worker_urls }
624
+ | Router :: Random { worker_urls, .. }
593
625
| Router :: CacheAware { worker_urls, .. } => {
594
626
info ! ( "Worker {} health check passed" , worker_url) ;
595
627
let mut urls = worker_urls. write ( ) . unwrap ( ) ;
@@ -663,7 +695,7 @@ impl Router {
663
695
pub fn remove_worker ( & self , worker_url : & str ) {
664
696
match self {
665
697
Router :: RoundRobin { worker_urls, .. }
666
- | Router :: Random { worker_urls }
698
+ | Router :: Random { worker_urls, .. }
667
699
| Router :: CacheAware { worker_urls, .. } => {
668
700
let mut urls = worker_urls. write ( ) . unwrap ( ) ;
669
701
if let Some ( index) = urls. iter ( ) . position ( |url| url == & worker_url) {
0 commit comments