The persistent_session.py module#

Summary#

LumericalPersistentPythonSession

A PersistentPythonSession that tolerates long, silent operations.

Description#

Lumerical-tuned PersistentPythonSession.

The base ansys.common.mcp.PersistentPythonSession.execute ends its collection loop after 0.5 seconds of no data (helpers.py:353consecutive_empty_reads > 5) and on a caller-supplied timeout. Both early returns are hostile to Lumerical. A fresh FDTD() spends seconds in silent C-level work. The call gives up before the marker arrives, and the next call’s _drain_queues discards the late output as stale. Timeout returns also leave the stateful python -i REPL mid-statement and let a prior call’s stale marker satisfy the next call’s wait loop.

This subclass re-implements execute with unbounded, marker-only termination. It waits indefinitely for a per-call ___EXEC____ marker matched by exact-line equality (so neither stale markers nor user code printing the token can end the wait), with a periodic process.poll() returning a distinct "Subprocess exited..." envelope if the child dies.

Hung snippets are recovered out-of-band via the restart_session MCP tool (PersistentPythonSession.restart()), issued as a parallel request. The wait loop polls a locally captured subprocess reference rather than self.process so a parallel restart() reassigning self.process cannot deadlock the wedged call on the new handle. The captured reference flips to an exit code when the original child is killed.

Module detail#

persistent_session.logger#