@@ -1302,3 +1302,79 @@ impl Default for ClientPerfMonitor {
1302
1302
Self :: new ( )
1303
1303
}
1304
1304
}
1305
+
1306
+ /// A combined monitor consisting of multiple [`Monitor`]s
1307
+ #[ derive( Debug , Clone ) ]
1308
+ pub struct CombinedMonitor < A , B > {
1309
+ first : A ,
1310
+ second : B ,
1311
+ start_time : Duration ,
1312
+ /// Client stats. This will be maintained to be consistent with
1313
+ /// client stats of first and second monitor.
1314
+ ///
1315
+ /// Currently, the client stats will be synced to first and second
1316
+ /// before each display call.
1317
+ client_stats : Vec < ClientStats > ,
1318
+ }
1319
+
1320
+ impl < A : Monitor , B : Monitor > CombinedMonitor < A , B > {
1321
+ /// Create a new combined monitor
1322
+ pub fn new ( mut first : A , mut second : B ) -> Self {
1323
+ let start_time = current_time ( ) ;
1324
+ first. set_start_time ( start_time) ;
1325
+ second. set_start_time ( start_time) ;
1326
+ Self {
1327
+ first,
1328
+ second,
1329
+ start_time,
1330
+ client_stats : vec ! [ ] ,
1331
+ }
1332
+ }
1333
+ }
1334
+
1335
+ impl < A : Monitor , B : Monitor > Monitor for CombinedMonitor < A , B > {
1336
+ fn client_stats_mut ( & mut self ) -> & mut Vec < ClientStats > {
1337
+ & mut self . client_stats
1338
+ }
1339
+
1340
+ fn client_stats ( & self ) -> & [ ClientStats ] {
1341
+ & self . client_stats
1342
+ }
1343
+
1344
+ fn start_time ( & self ) -> Duration {
1345
+ self . start_time
1346
+ }
1347
+
1348
+ fn set_start_time ( & mut self , time : Duration ) {
1349
+ self . start_time = time;
1350
+ self . first . set_start_time ( time) ;
1351
+ self . second . set_start_time ( time) ;
1352
+ }
1353
+
1354
+ fn display ( & mut self , event_msg : & str , sender_id : ClientId ) {
1355
+ self . first . client_stats_mut ( ) . clone_from ( & self . client_stats ) ;
1356
+ self . first . display ( event_msg, sender_id) ;
1357
+ self . second
1358
+ . client_stats_mut ( )
1359
+ . clone_from ( & self . client_stats ) ;
1360
+ self . second . display ( event_msg, sender_id) ;
1361
+ }
1362
+
1363
+ fn aggregate ( & mut self , name : & str ) {
1364
+ self . first . aggregate ( name) ;
1365
+ self . second . aggregate ( name) ;
1366
+ }
1367
+ }
1368
+
1369
+ /// Variadic macro to create a chain of [`Monitor`]
1370
+ #[ macro_export]
1371
+ macro_rules! combine_monitor {
1372
+ ( $last: expr ) => { $last } ;
1373
+
1374
+ ( $last: expr, ) => { $last } ;
1375
+
1376
+ ( $head: expr, $( $tail: expr) ,+ $( , ) ?) => {
1377
+ // recursive call
1378
+ $crate:: monitors:: CombinedMonitor :: new( $head , $crate:: combine_monitor!( $( $tail) ,+) )
1379
+ } ;
1380
+ }
0 commit comments