Describe the bug
MonteCarlo.simulate() returns normally after the user interrupts a run.
In serial mode, __run_in_serial() catches KeyboardInterrupt, prints that files were saved, appends the current input record to the error file, and then returns. In parallel mode, __run_in_parallel() catches KeyboardInterrupt, signals and joins the workers, but only re-raises non-keyboard exceptions.
The public simulate() method then calls __terminate_simulation() and returns as if the requested number of simulations completed. Callers cannot distinguish a partial run from a successful one without inspecting the output files.
To reproduce
Start a serial or parallel Monte Carlo run and interrupt it with Ctrl-C. At cb6106a717207dd8fc2dfe1446d80ff75022f21b, control returns normally after the cleanup message instead of propagating KeyboardInterrupt.
Expected behavior
RocketPy should preserve completed rows and stop or join active workers, then re-raise the original KeyboardInterrupt. This lets command-line callers return the conventional interrupted status and lets Python callers handle a partial run explicitly.
The saved files should remain usable with the documented append=True continuation path.
Proposed fix
Keep the current cleanup and file-preservation behavior in both execution modes, but re-raise after cleanup. Add serial and parallel regression tests that verify:
- completed rows remain readable;
- workers are signalled and joined;
__terminate_simulation() does not convert the interrupted run into success;
- the caller receives
KeyboardInterrupt.
The relevant control flow is also being changed by #1054, so implementation should follow that pull request rather than introducing a conflicting parallel-run rewrite.
Environment
- Base SHA:
cb6106a717207dd8fc2dfe1446d80ff75022f21b
- RocketPy 1.13.0
- Python 3.12.6
- NumPy 2.5.2
- SciPy 1.18.0
- pytest 9.1.1
- macOS 26.5.2, arm64
Describe the bug
MonteCarlo.simulate()returns normally after the user interrupts a run.In serial mode,
__run_in_serial()catchesKeyboardInterrupt, prints that files were saved, appends the current input record to the error file, and then returns. In parallel mode,__run_in_parallel()catchesKeyboardInterrupt, signals and joins the workers, but only re-raises non-keyboard exceptions.The public
simulate()method then calls__terminate_simulation()and returns as if the requested number of simulations completed. Callers cannot distinguish a partial run from a successful one without inspecting the output files.To reproduce
Start a serial or parallel Monte Carlo run and interrupt it with Ctrl-C. At
cb6106a717207dd8fc2dfe1446d80ff75022f21b, control returns normally after the cleanup message instead of propagatingKeyboardInterrupt.Expected behavior
RocketPy should preserve completed rows and stop or join active workers, then re-raise the original
KeyboardInterrupt. This lets command-line callers return the conventional interrupted status and lets Python callers handle a partial run explicitly.The saved files should remain usable with the documented
append=Truecontinuation path.Proposed fix
Keep the current cleanup and file-preservation behavior in both execution modes, but re-raise after cleanup. Add serial and parallel regression tests that verify:
__terminate_simulation()does not convert the interrupted run into success;KeyboardInterrupt.The relevant control flow is also being changed by #1054, so implementation should follow that pull request rather than introducing a conflicting parallel-run rewrite.
Environment
cb6106a717207dd8fc2dfe1446d80ff75022f21b