asynchronics / asynchronix

High-performance asynchronous computation framework for system simulation
Apache License 2.0
170 stars 9 forks source link

Type erased address type #16

Open robamu opened 6 months ago

robamu commented 6 months ago

Is there some way to get type erased variants of the address type and work with those when sending or scheduling events?

I have a struct like this

// The simulation controller processes requests and drives the simulation.
pub struct SimController {
    pub sys_clock: SystemClock,
    pub request_receiver: mpsc::Receiver<SimRequest>,
    pub simulation: Simulation,
    pub mgm_addr: Address<MagnetometerModel>,
    pub pcdu_addr: Address<PcduModel>,
}

where I need to keep the address handles for each distinct model type to send or schedule events to these devices. I think if I scale up my simulation to a large number of devices, the number of fields in this struct, and the effort to always update the SimController construction might get unwieldy. A type-erased variant would allow something like HashMap<ModelId, Address> to be used. But there are probably technical limitations due to the way generics are used here?

sbarral commented 6 months ago

I have something very similar already in my (for now private) experiment with RPC, but this is all very much in flux. What I have is actually more general, like an Output<T>, i.e. it is only bound to the event type and can be connected to multiple models, but instead of generating a future when "sending" an event, it generates a deferred Action that can be scheduled or processed immediately using something like Simulation::schedule_action(deadline, action).

I could publish this WIP if you want, but I would not recommend using it before it stabilizes.

As a stopgap measure, you could define a trait to abstract over that, something like:

trait EventSender<T> {
    fn schedule_event(simulation: &mut Simulation, event: T) -> -> Result<(), SchedulingError>;
    fn schedule_keyed_event(simulation: &mut Simulation, event: T) -> -> Result<EventKey, SchedulingError>;
    ...
}

and then implement it on a parametrized type that stores the Address and the relevant InputFn closure for the target model. Not super-elegant but it should work...

In any case, I'd keep this issue open until the WIP solution arrives officially in v0.3.

robamu commented 6 months ago

If there is already something WIP, I am okay with waiting 👍 The complexity if still manageable for me.