@@ -4,7 +4,6 @@ use ott_balancer_protocol::monolith::{
4
4
B2MClientMsg , B2MJoin , B2MLeave , B2MUnload , MsgB2M , MsgM2B , RoomMetadata ,
5
5
} ;
6
6
use ott_balancer_protocol:: * ;
7
- use rand:: seq:: IteratorRandom ;
8
7
use serde_json:: value:: RawValue ;
9
8
use tokio:: sync:: RwLock ;
10
9
use tokio_tungstenite:: tungstenite:: protocol:: frame:: coding:: CloseCode ;
@@ -16,6 +15,7 @@ use crate::client::ClientLink;
16
15
use crate :: config:: BalancerConfig ;
17
16
use crate :: monolith:: Room ;
18
17
use crate :: room:: RoomLocator ;
18
+ use crate :: selection:: { MinRoomsSelector , MonolithSelection } ;
19
19
use crate :: {
20
20
client:: { BalancerClient , NewClient } ,
21
21
messages:: * ,
@@ -171,12 +171,25 @@ impl BalancerLink {
171
171
}
172
172
}
173
173
174
- #[ derive( Debug , Default ) ]
174
+ #[ derive( Debug ) ]
175
175
pub struct BalancerContext {
176
176
pub clients : HashMap < ClientId , BalancerClient > ,
177
177
pub monoliths : HashMap < MonolithId , BalancerMonolith > ,
178
178
pub rooms_to_monoliths : HashMap < RoomName , RoomLocator > ,
179
179
pub monoliths_by_region : HashMap < String , Vec < MonolithId > > ,
180
+ pub monolith_selection : Box < dyn MonolithSelection + Send + Sync + ' static > ,
181
+ }
182
+
183
+ impl Default for BalancerContext {
184
+ fn default ( ) -> Self {
185
+ BalancerContext {
186
+ clients : HashMap :: default ( ) ,
187
+ monoliths : HashMap :: default ( ) ,
188
+ rooms_to_monoliths : HashMap :: default ( ) ,
189
+ monoliths_by_region : HashMap :: default ( ) ,
190
+ monolith_selection : Box :: < MinRoomsSelector > :: default ( ) ,
191
+ }
192
+ }
180
193
}
181
194
182
195
impl BalancerContext {
@@ -356,50 +369,29 @@ impl BalancerContext {
356
369
Ok ( monolith)
357
370
}
358
371
359
- /// When loading a room, call this to select the best monolith to load it on.
360
- pub fn select_monolith ( & self ) -> anyhow:: Result < & BalancerMonolith > {
361
- fn cmp ( x : & BalancerMonolith , y : & BalancerMonolith ) -> std:: cmp:: Ordering {
362
- x. rooms ( ) . len ( ) . cmp ( & y. rooms ( ) . len ( ) )
363
- }
364
-
372
+ /// Prioritizes monoliths in the same region
373
+ pub fn filter_monoliths ( & self ) -> Vec < & BalancerMonolith > {
365
374
let in_region = self
366
375
. monoliths_by_region
367
376
. get ( BalancerConfig :: get ( ) . region . as_str ( ) ) ;
368
377
if let Some ( in_region) = in_region {
369
- let selected = in_region
378
+ return in_region
370
379
. iter ( )
371
380
. flat_map ( |id| self . monoliths . get ( id) )
372
- . min_by ( |x, y| cmp ( x, y) ) ;
373
- if let Some ( s) = selected {
374
- return Ok ( s) ;
375
- }
376
- }
377
- let selected = self . monoliths . values ( ) . min_by ( |x, y| cmp ( x, y) ) ;
378
- match selected {
379
- Some ( s) => Ok ( s) ,
380
- None => anyhow:: bail!( "no monoliths available" ) ,
381
+ . collect ( ) ;
381
382
}
383
+
384
+ self . monoliths . values ( ) . collect ( )
382
385
}
383
386
384
- pub fn random_monolith ( & self ) -> anyhow:: Result < & BalancerMonolith > {
385
- let in_region = self
386
- . monoliths_by_region
387
- . get ( BalancerConfig :: get ( ) . region . as_str ( ) ) ;
388
- if let Some ( in_region) = in_region {
389
- let selected = in_region. iter ( ) . choose ( & mut rand:: thread_rng ( ) ) ;
390
- if let Some ( s) = selected {
391
- if let Some ( m) = self . monoliths . get ( s) {
392
- return Ok ( m) ;
393
- }
394
- }
395
- }
387
+ pub fn select_monolith ( & self ) -> anyhow:: Result < & BalancerMonolith > {
388
+ let filtered = self . filter_monoliths ( ) ;
389
+ return self . monolith_selection . select_monolith ( filtered) ;
390
+ }
396
391
397
- let selected = self
398
- . monoliths
399
- . values ( )
400
- . choose ( & mut rand:: thread_rng ( ) )
401
- . ok_or ( anyhow:: anyhow!( "no monoliths available" ) ) ?;
402
- Ok ( selected)
392
+ pub fn random_monolith ( & self ) -> anyhow:: Result < & BalancerMonolith > {
393
+ let filtered = self . filter_monoliths ( ) ;
394
+ return self . monolith_selection . random_monolith ( filtered) ;
403
395
}
404
396
405
397
#[ instrument( skip( self , monolith) , err, fields( monolith_id = %monolith) ) ]
0 commit comments