This PR makes it possible to cancel events up to the very last moment, even if the event is scheduled for the current time. This closes #3 .
How it works
The previous implementation relied on a custom priority queue that allowed events to be deleted using an identifier returned when scheduling events. This worked well but did not allow cancellation of current-time events since current events have already been dispatched from the priority queue to the models' mailboxes.
The new implementation relies instead on shared handles called EventKeys (basically, an Arc wrapping the state of the event) which are returned when events are scheduled. The user can use such a handle to cancel the event. The priority queue and the future that processes the event at the model level also each have a cloned handle to check if the event was cancelled. These checks are performed twice: first when the event is pulled from the priority queue (to avoid dispatching cancelled events) and then when the event is about to be processed by the model.
Impact
Since creating an EventKey has a cost (Arc allocation and cloning), the methods schedule_at in Simulation and Scheduler were each replaced by two methods: schedule_event_at, which does not create an event key, and schedule_keyed_event_at, which returns an event key. Likewise with the former schedule_in methods.
With this change, the impact on performance is expected to be negligible (perhaps even positive since cancelling an event no longer requires acquiring a lock on the priority queue).
Goal
This PR makes it possible to cancel events up to the very last moment, even if the event is scheduled for the current time. This closes #3 .
How it works
The previous implementation relied on a custom priority queue that allowed events to be deleted using an identifier returned when scheduling events. This worked well but did not allow cancellation of current-time events since current events have already been dispatched from the priority queue to the models' mailboxes.
The new implementation relies instead on shared handles called
EventKey
s (basically, anArc
wrapping the state of the event) which are returned when events are scheduled. The user can use such a handle to cancel the event. The priority queue and the future that processes the event at the model level also each have a cloned handle to check if the event was cancelled. These checks are performed twice: first when the event is pulled from the priority queue (to avoid dispatching cancelled events) and then when the event is about to be processed by the model.Impact
Since creating an
EventKey
has a cost (Arc
allocation and cloning), the methodsschedule_at
inSimulation
andScheduler
were each replaced by two methods:schedule_event_at
, which does not create an event key, andschedule_keyed_event_at
, which returns an event key. Likewise with the formerschedule_in
methods.With this change, the impact on performance is expected to be negligible (perhaps even positive since cancelling an event no longer requires acquiring a lock on the priority queue).