async fn send(&self, event: &Event) -> Result<(), ModelError> {
        // Copy the senders so we don't hold onto the sender map lock
        // If we didn't do this, it is possible to deadlock while holding onto this lock.
        // For example,
        // Task A : call send(event1) -> lock on sender map -> send -> wait for responders
        // Task B : call send(event2) -> lock on sender map
        // If task B was required to respond to event1, then this is a deadlock.
        // Neither task can make progress.
        let senders = {
            let sender_map = self.sender_map.lock().await;
            if let Some(senders) = sender_map.get(&event.payload.type_()) {
                senders.clone()
            } else {
                // There were no senders for this event. Do nothing.
                return Ok(());
            }
        };

        let mut responder_channels = vec![];
        for sender in senders {
            let result = sender.send(event.clone()).await;
            match result {
                Ok(responder_channel) => {
                    // A future can be canceled if the receiver was dropped after
                    // a send. We don't crash the system when this happens. It is
                    // perfectly valid for a receiver to be dropped. That simply
                    // means that the receiver is no longer interested in future
                    // events. So we force each future to return a success. This
                    // ensures that all the futures can be driven to completion.
                    let responder_channel = async move {
                        trace::duration!("component_manager", "breakpoints:wait_for_resume");
                        let result = responder_channel.await;
                        trace::flow_end!("component_manager", "event", event.id);
                        if let Err(error) = result {
                            warn!(
                                "A responder channel was canceled. This may \
                                 mean that an InvocationReceiver was dropped \
                                 unintentionally. Error -> {}",
                                error
                            );
                        }
                    };
                    responder_channels.push(responder_channel);
                }
                Err(error) => {
                    // A send can fail if the receiver was dropped. We don't
                    // crash the system when this happens. It is perfectly
                    // valid for a receiver to be dropped. That simply means
                    // that the receiver is no longer interested in future
                    // events.
                    warn!(
                        "Failed to send event via InvocationSender. \
                         This may mean that an InvocationReceiver was dropped \
                         unintentionally. Error -> {}",
                        error
                    );
                }
            }
        }

        // Wait until all tasks have used the responder to unblock.
        {
            trace::duration!("component_manager", "breakpoints:wait_for_all_resume");
            futures::future::join_all(responder_channels).await;
        }

        Ok(())
    }
/// Sends the event to all registered breakpoints and waits to be unblocked by all
Sends the event to all registered breakpoints and waits to be unblocked by all
Sends the event to all registered breakpoints and waits to be unblocked by all
async fn send(&self, event: &Event) -> Result<(), ModelError> {
        // Copy the senders so we don't hold onto the sender map lock
        // If we didn't do this, it is possible to deadlock while holding onto this lock.
        // For example,
        // Task A : call send(event1) -> lock on sender map -> send -> wait for responders
        // Task B : call send(event2) -> lock on sender map
        // If task B was required to respond to event1, then this is a deadlock.
        // Neither task can make progress.
        let senders = {
            let sender_map = self.sender_map.lock().await;
            if let Some(senders) = sender_map.get(&event.payload.type_()) {
                senders.clone()
            } else {
                // There were no senders for this event. Do nothing.
                return Ok(());
            }
        };
        let mut responder_channels = vec![];
        for sender in senders {
            let result = sender.send(event.clone()).await;
            match result {
                Ok(responder_channel) => {
                    // A future can be canceled if the receiver was dropped after
                    // a send. We don't crash the system when this happens. It is
                    // perfectly valid for a receiver to be dropped. That simply
                    // means that the receiver is no longer interested in future
                    // events. So we force each future to return a success. This
                    // ensures that all the futures can be driven to completion.
                    let responder_channel = async move {
                        trace::duration!("component_manager", "breakpoints:wait_for_resume");
                        let result = responder_channel.await;
                        trace::flow_end!("component_manager", "event", event.id);
                        if let Err(error) = result {
                            warn!(
                                "A responder channel was canceled. This may \
                                 mean that an InvocationReceiver was dropped \
                                 unintentionally. Error -> {}",
                                error
                            );
                        }
                    };
                    responder_channels.push(responder_channel);
                }
                Err(error) => {
                    // A send can fail if the receiver was dropped. We don't
                    // crash the system when this happens. It is perfectly
                    // valid for a receiver to be dropped. That simply means
                    // that the receiver is no longer interested in future
                    // events.
                    warn!(
                        "Failed to send event via InvocationSender. \
                         This may mean that an InvocationReceiver was dropped \
                         unintentionally. Error -> {}",
                        error
                    );
                }
            }
        }
        // Wait until all tasks have used the responder to unblock.
        {
            trace::duration!("component_manager", "breakpoints:wait_for_all_resume");
            futures::future::join_all(responder_channels).await;
        }
        Ok(())
    }
async fn send ( & self , event : & Event ) -> Result < ( ) , ModelError > { // Copy the senders so we don't hold onto the sender map lock // If we didn't do this, it is possible to deadlock while holding onto this lock. // For example, // Task A : call send(event1) -> lock on sender map -> send -> wait for responders // Task B : call send(event2) -> lock on sender map // If task B was required to respond to event1, then this is a deadlock. // Neither task can make progress. let senders = { let sender_map = self . sender_map . lock ( ) . await ; if let Some ( senders ) = sender_map . get ( & event . payload . type_ ( ) ) { senders . clone ( ) } else { // There were no senders for this event. Do nothing. return Ok ( ( ) ) ; } } ; let mut responder_channels = vec ! [ ] ; for sender in senders { let result = sender . send ( event . clone ( ) ) . await ; match result { Ok ( responder_channel ) => { // A future can be canceled if the receiver was dropped after // a send. We don't crash the system when this happens. It is // perfectly valid for a receiver to be dropped. That simply // means that the receiver is no longer interested in future // events. So we force each future to return a success. This // ensures that all the futures can be driven to completion. let responder_channel = async move { trace :: duration ! ( " " " " ) ; let result = responder_channel . await ; trace :: flow_end ! ( " " " " event id ) ; if let Err ( error ) = result { warn ! ( " \
 \
 " error ) ; } } ; responder_channels . push ( responder_channel ) ; } Err ( error ) => { // A send can fail if the receiver was dropped. We don't // crash the system when this happens. It is perfectly // valid for a receiver to be dropped. That simply means // that the receiver is no longer interested in future // events. warn ! ( " \
 \
 " error ) ; } } } // Wait until all tasks have used the responder to unblock. { trace :: duration ! ( " " " " ) ; futures :: future :: join_all ( responder_channels ) . await ; } Ok ( ( ) ) }
Sends the event to all registered breakpoints and waits to be unblocked by all
Sends the event to all registered breakpoints and waits to be unblocked by all
&self
event
&Event