Skip to content

bridge-v0.2.4

Choose a tag to compare

@github-actions github-actions released this 15 Apr 12:01
· 87 commits to master since this release

Highlights

Aligns task lifetime with cycling lifetime — wait=False O.run no longer creates silent-success bugs or orphan cycling.

What's fixed

Previously when a script called O.run(N) with wait=False, the task could complete in milliseconds while cycling continued in the background, leading to:

  • Silent success — cycling errors (e.g. a PyRunner raising NameError → <FATAL ERROR> in C++) were swallowed; the task was marked completed even though the simulation had died on iter 1.
  • Orphan cycling — the simulation kept running after the task exited, outliving task boundaries and escaping interrupt_task (which reads an interrupt flag keyed by _current_task_id, cleared at script exit).
  • Broken interrupt path — for scripts that survived via a poll loop (e.g. while O.iter < target: time.sleep(...)), the main thread was locked in user code and no interrupt could reach it.

What changed

  • ScriptRunner._execute: after user exec() returns, drain any still-live cycling via O.wait(). Cycling errors re-raise as RuntimeError through the existing except path; the interrupt flag is re-checked post-wait so the task correctly transitions to interrupted when requested.
  • handle_interrupt_task: removed the now-redundant out-of-band O.pause() call from the websocket thread — PyRunner tick + drain cover all interrupt paths. Response schema drops paused_from_ws_thread.

Behaviour after this release

Scenario Task status Duration
Clean O.run(N, wait=False) completed waits for N iters to finish (not instant)
O.run(N, wait=False) with cycling error failed with exception_type=RuntimeError short — O.wait() surfaces the error
yade_interrupt_task during drain interrupted returns within one PyRunner tick

Task lifetime now equals cycling lifetime — matching PFC's synchronous SDK model.

Recommended script pattern for long simulations

for _ in range(n_chunks):
    O.run(chunk_size, wait=True)
    save_checkpoint(O.iter)
    print(f"iter={O.iter} ...")

Gives progress visibility, checkpointing, clean interrupt response, and incidental GUI breathing room between chunks. Avoid O.run(N) wait=False paired with a poll loop.

Tests

6 new unit tests cover the drain semantics (tests/bridge/test_script_drain.py); full bridge suite at 137 passing.

Full Changelog: bridge-v0.2.2...bridge-v0.2.4