The basic setup:
- There are multiple different event loops that abstract over a processing function
- The processing function abstract over multiple response channel types
In the absence of HKTs we can't pass a type generic function as generic type into the event loop functions. So I went with trait objects. The trait object for response channel must be clone-able in a thread compatible way, ie. requiring Arc. This leaves me with:
pub trait ResponseChannel: Send + Sync + Debug {
// Takes self by const ref to allow the process function to share the channel across multiple
// threads.
fn send(&self, response: Vec<u8>) -> Result<(), ResponseError>;
}
pub type ProcessFn =
dyn Fn(&[u8], Arc<dyn ResponseChannel>) -> Result<(), ResponseError> + Send + Sync;
pub fn event_loop_a(config: &Config, process_fn: &ProcessFn) {
let response_channel = Arc::new(MqResponseChannel {
message_queue: config.mq_ring.server_mq.clone(),
});
[...]
}
#[derive(Clone, Debug)]
struct MqResponseChannel {
message_queue: Arc<SegQueue<Vec<u8>>>,
}
// Other event loops ...
I'm unhappy with the double Arc indirection. How could this be avoided?