add pause and resume to EventGenerator#3431
Conversation
|
Performance benchmarks:
|
|
I am open to considering this PR, but I fail to see a clear use case for it. So can you give some examples of when this might be useful? |
|
The main situation I had in mind is when a recurring process exists in the model but becomes temporarily inactive because of state changes. For example, an agent might have some recurring behavior that runs every few ticks. If the agent becomes inactive for a while the user might want to suspend that behavior and later resume it when the agent becomes active again. In that case So the idea is mainly to model processes that temporarily stop due to state changes but are expected to continue later, rather than being permanently terminated. |
|
I've been thinking about a few example use cases and here's what i came up with. One example comes from the Boltzmann Wealth model. Agents repeatedly move and exchange wealth. If expressed as a recurring process instead of the step() loop, an agent could temporarily stop participating in exchanges when it has no wealth and resume once it receives wealth again. self.trade_process = EventGenerator(
model,
self.trade,
Schedule(interval=1.0),
).start()
def trade(self):
self.move()
if self.wealth <= 0:
self.trade_process.pause()
return
self.give_money()
def receive_money(self):
self.wealth += 1
if self.trade_process.is_paused:
self.trade_process.resume()Another example is the Wolf–Sheep model. Sheep and wolves lose energy every step and eventually die if their energy becomes negative. If this were expressed as a recurring process instead of a step() loop, an agent might pause its recurring behavior when it dies and resume if it later becomes active again. self.behavior = EventGenerator(
model,
self.step_behavior,
Schedule(interval=1.0),
).start()
def step_behavior(self):
self.move()
self.energy -= 1
if self.energy < 0:
self.behavior.pause()
return
self.feed()In both situations the process is temporarily inactive due to state changes but expected to continue later, so pause() and resume() avoids having to destroy and recreate the generator with stop() and start(). |
|
Thanks for this. I have been thinking about this myself a bit as well. I actually think that a better use case is some random arrival process. Say we have a Poisson arrival process for some supermarket. This arrival process is only active when the store is open, but during off-hours, we might want to pause it (and schedule its reactivation for the next day). |
|
@quaquel can you tag me as a reviewer on PRs related to time and events? |
Summary
This PR adds pause and resume methods to EventGenerator to allow temporarily suspending recurring event execution without terminating the generator.
After the addition of
next_scheduled_timein #3423, this continues the improvements proposed in #3420 to make the lifecycle and scheduling state of EventGenerator clearer and easier to control.Motive
Currently EventGenerator only has start and stop for lifecycle control. stop() fully terminates the generator and removes it from the model, which means temporarily suspending event generation requires restarting the generator again.
In some simulations it is useful to pause recurring behavior temporarily and later continue it without resetting the generator lifecycle. Providing explicit pause and resume methods allows this type of control without requiring users to manipulate internal state or restart generators.
Implementation
_pausedstate flag._execute_and_rescheduleso events are not rescheduled while the generator is paused.The design intentionally keeps the API minimal and builds on the existing scheduling logic rather than introducing additional scheduling parameters.
Usage Examples
Additional Notes