Using DEVSimulator: How to prevent simulation from stopping when no events are present?
Problem Description:
I am using DEVSimulator in a Mesa-based simulation, and I noticed that when there are no events in the queue, the simulation stops running. This behavior is problematic when I want to keep the simulation running indefinitely and allow new events to be scheduled dynamically.
Expected Behavior:
- When there are no events, the simulation should not stop completely but rather wait for new events to be scheduled (or continue advancing time at a fixed interval).
- Is there a built-in way to handle this behavior in
DEVSimulator?
Current Workaround:
To prevent the simulation from stopping, I am considering:
- scheduling a periodic "idle" event that does nothing but keeps the queue active. such as:
def idle_event(model):
# idle event can do nothing or just update the time
pass
# Schedule a periodic idle event after the simulator is initialized (e.g. before run_for())
def schedule_idle_events(simulator, interval=1):
# schedule an idle event every interval seconds
simulator.schedule_event_relative(idle_event, interval, function_kwargs={'model': simulator.model})
# call itself to ensure loop
simulator.schedule_event_relative(schedule_idle_events, interval, function_kwargs={'simulator': simulator, 'interval': interval})
# schedule the idle event immediately once initializing the simulator
schedule_idle_events(simulator, interval=1)
-
Modifying the event processing loop(function
run_until) to wait instead of stopping when the queue is empty. such as:
def run_until(self, end_time):
while self.time < end_time:
try:
event = self.event_list.pop_event()
except IndexError:
# the queue is empty, wait for a while, and then continue the cycle
time.sleep(0.1)
continue
self.time = event.time
event.execute()
Is there a recommended way to handle this within DEVSimulator, or is this expected behavior?
Steps to Reproduce:
- Create a
DEVSimulator-based simulation. - Run it until all scheduled events are completed.
- Observe that the simulation stops running.
System Info:
- Mesa version: 3.1.4
- Python version: 3.11.6
- OS: macOS Sequoia 15.2
Any guidance on the best approach would be greatly appreciated!
If there is no next event scheduled, there is nothing the DEVS scheduler can advance to. This is the definition of the next event time progression and conforms to all specs and formalizations of DEVS. So the behavior is, in my view, correct. In fact, in DEVS events themselves drive the simulation by potentially resulting in new events being scheduled.
The notion of an idle event likewise makes no sense to me. Events imply that some state update takes place. So an empty event is meaningless.
I don't understand the waiting you describe. Where can new events come from except from the execution of existing events?
Perhaps it helps if you can take a step back and give a minimum example of what you are trying to do.
If there is no next event scheduled, there is nothing the DEVS scheduler can advance to. This is the definition of the next event time progression and conforms to all specs and formalizations of DEVS. So the behavior is, in my view, correct. In fact, in DEVS events themselves drive the simulation by potentially resulting in new events being scheduled.
The notion of an idle event likewise makes no sense to me. Events imply that some state update takes place. So an empty event is meaningless.
I don't understand the waiting you describe. Where can new events come from except from the execution of existing events?
Perhaps it helps if you can take a step back and give a minimum example of what you are trying to do.
Thank you for your response! I understand that in DEVS, events drive the simulation, and without an event to process, the simulator has no logical next step.
However, in my case, the simulation is interacting with an external data source. Specifically:
- A separate thread periodically fetches new data (not generated by existing events).
- Once new data arrives, I need to process it using DEVSimulator.
- Since the data is not available in real-time, there are moments where no events are scheduled, but I still need the simulation to continue running and be able to accept new events dynamically.
This is why I prefer method 2—modifying the event loop to avoid stopping when the queue is empty. The goal is to allow the simulation to "wait" rather than terminate when no events are immediately available, enabling it to process events when they arrive asynchronously.
Would you suggest an alternative approach to achieve this while maintaining consistency with DEVS principles?
You don't need to change anything inside mesa for this. Just schedule an event for the current time step with a while loop:
while self.model.simulator.eventlist.is_empty():
time.sleep(0.1)
Hi, I’m really interested in working on this task for GSoC and was wondering if I could be assigned to it? I’d love to get started as soon as possible, as the GSoC application deadline is coming up.
Hi @rafia-10, thanks a lot for your interest and enthusiasm! 🙌
You're absolutely welcome to explore this task and propose improvements. Just to clarify, a potential workaround has already been discussed above (see @quaquel’s suggestion using a while loop to wait for the eventlist to be non-empty), so you might want to consider that when shaping your proposal. That said, if you believe there’s a more elegant or robust approach, I’d love to see your ideas!
Let me know if you need any help getting started!