[RFC] Relay service event handling#856
Conversation
To make sure I understand, the UART service would be responsible for listening for events and sending them to a host over UART? And the question is to how to make the service generic over any possible event type? I don't think we can be generic in the sense that we don't have to provide service-specific code. Having a single |
In a generic sense, any relay service is responsible for listening for events from all the relayable services and is responsible for deciding which events are considered "notifiable" and then how exactly to properly notify the host of that event. Some relay services would just use a "doorbell" form of notification (so no payload, just for example asserting a gpio line that the host agrees on means "I need attention"). Some might decide to notify via payloads (for example, the mctp uart service could just send a payload directly via TX). The HID services also handle notifications in some specific way. I'm just trying to figure out how to best pass the knowledge of this constructed |
So relay services need to be able to listen for events from all relayable services to then decide which are worth notifying to the host.
This was challenging, especially since I wanted to make use of the generic Sender/Receiver traits introduced by Robert. Basically what I decided on was to introduce two new Receiver types: a
MapReceiverand aMuxReceiver.The
MapReceivercan map events to another type, and theMuxReceivercan combine multiple receivers into a common event type. E.g. for services:Thermal serivce -> ThermalEvent
Battery service -> BatteryEvent
etc
We need a common
ServiceEventtype that might look like:so a MapReceiver would map a Receiver to a Receiver like:
MapReciever::new(Receiver<ThermalEvent>, ServiceEvent::Thermal)and a battery event like:
MapReciever::new(Receiver<BatteryEvent>, ServiceEvent::BatteryEvent)and the MuxReceiver under the hood uses MapReceiver to mux together these events using
withchains:MuxReceiver::new().with(Receiver<ThermalEvent>, ServiceEvent::Thermal).with(Receiver<BatteryEvent>, ServiceEvent::Battery)That internally selects over all its receivers and produces a flattened
ServiceEventtype.This seems like the best way to combine N generic Receivers into one.
However, still don't have a perfect solution for how to use this within relay services. I updated the mctp relay handler macro to generate a
ServiceEventenum based on the passed in service handlers, and it also generates a function that builds theMuxReceiverusingwithchains.My original idea was this macro'd MuxReceiver for ServiceEvent can be passed to a relay service just like we pass a relay handler (so the relay service can wait for any event from a relayable serivce, then decide how to notify the host). But, the problem is how does the relay service know what the events are, since they are constructed via macro?
For example, the uart service can't do:
because it doesn't have knowledge of the constructed
ServiceEventtype. So need to think this part through some more.