Avoiding double Arc indirection

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?