@@ -39,6 +39,7 @@ use std::{
39
39
sync:: OnceLock ,
40
40
} ;
41
41
42
+ use ahash:: AHashMap ;
42
43
use handler:: ShareableMessageHandler ;
43
44
use indexmap:: IndexMap ;
44
45
use nautilus_core:: UUID4 ;
@@ -86,6 +87,21 @@ pub fn send(endpoint: &Ustr, message: &dyn Any) {
86
87
}
87
88
}
88
89
90
+ /// Sends the `response` to the handler registered for the `correlation_id` (if found).
91
+ pub fn response ( correlation_id : & UUID4 , message : & dyn Any ) {
92
+ let handler = get_message_bus ( )
93
+ . borrow ( )
94
+ . get_response_handler ( correlation_id)
95
+ . cloned ( ) ;
96
+ if let Some ( handler) = handler {
97
+ handler. 0 . handle ( message) ;
98
+ } else {
99
+ log:: error!(
100
+ "Failed to handle response: handler not found for correlation_id {correlation_id}"
101
+ )
102
+ }
103
+ }
104
+
89
105
/// Publishes the `message` to the `topic`.
90
106
pub fn publish ( topic : & Ustr , message : & dyn Any ) {
91
107
log:: trace!( "Publishing topic '{topic}' {message:?}" ) ;
@@ -303,8 +319,10 @@ pub struct MessageBus {
303
319
/// Maps a pattern to all the handlers registered for it
304
320
/// this is updated whenever a new subscription is created.
305
321
patterns : IndexMap < Ustr , Vec < Subscription > > ,
306
- /// Handles a message or a request destined for a specific endpoint .
322
+ /// Index of endpoint addresses and their handlers .
307
323
endpoints : IndexMap < Ustr , ShareableMessageHandler > ,
324
+ /// Index of request correlation IDs and their response handlers.
325
+ correlation_index : AHashMap < UUID4 , ShareableMessageHandler > ,
308
326
}
309
327
310
328
// SAFETY: Message bus is not meant to be passed between threads
@@ -328,6 +346,7 @@ impl MessageBus {
328
346
subscriptions : IndexMap :: new ( ) ,
329
347
patterns : IndexMap :: new ( ) ,
330
348
endpoints : IndexMap :: new ( ) ,
349
+ correlation_index : AHashMap :: new ( ) ,
331
350
has_backing : false ,
332
351
}
333
352
}
@@ -401,12 +420,19 @@ impl MessageBus {
401
420
// TODO: Integrate the backing database
402
421
Ok ( ( ) )
403
422
}
423
+
404
424
/// Returns the handler for the given `endpoint`.
405
425
#[ must_use]
406
426
pub fn get_endpoint < T : AsRef < str > > ( & self , endpoint : T ) -> Option < & ShareableMessageHandler > {
407
427
self . endpoints . get ( & Ustr :: from ( endpoint. as_ref ( ) ) )
408
428
}
409
429
430
+ /// Returns the handler for the given `correlation_id`.
431
+ #[ must_use]
432
+ pub fn get_response_handler ( & self , correlation_id : & UUID4 ) -> Option < & ShareableMessageHandler > {
433
+ self . correlation_index . get ( correlation_id)
434
+ }
435
+
410
436
#[ must_use]
411
437
pub fn matching_subscriptions ( & self , pattern : & Ustr ) -> Vec < Subscription > {
412
438
let mut matching_subs: Vec < Subscription > = Vec :: new ( ) ;
@@ -433,6 +459,22 @@ impl MessageBus {
433
459
matching_subs
434
460
}
435
461
462
+ pub fn register_response_handler (
463
+ & mut self ,
464
+ correlation_id : & UUID4 ,
465
+ handler : ShareableMessageHandler ,
466
+ ) -> anyhow:: Result < ( ) > {
467
+ if self . correlation_index . contains_key ( correlation_id) {
468
+ return Err ( anyhow:: anyhow!(
469
+ "Correlation ID <{correlation_id}> already has a registered handler" ,
470
+ ) ) ;
471
+ }
472
+
473
+ self . correlation_index . insert ( * correlation_id, handler) ;
474
+
475
+ Ok ( ( ) )
476
+ }
477
+
436
478
fn matching_handlers < ' a > (
437
479
& ' a self ,
438
480
pattern : & ' a Ustr ,
0 commit comments