OMPython
OMPython copied to clipboard
Possible for ZMQ freezes when receiving data
A similar issue to https://github.com/OpenModelica/OMJulia.jl/issues/12 could occur here as @arun3688 pointed out. I leave this issue as an open issue here as well.
Some kind of polling should be implemented to prevent this
@lochel @arun3688
I think @lochel knows exactly what this issue is and how to solve it : ) (If it exists for OMPython as it does for OMJulia)
I just hit this issue, too when trying to interrupt OMPython with Ctrl-C, which turns out to be impossible while it's waiting for a reply via the ZMQ socket.
The problem is that a ZMQ self._omc.recv_string()
does not receive the interrupt, so the raisedKeyboardInterrupt
only kills the Python side, leading to a frozen program -- you can only kill the process externally.
Two solutions that are mentioned at https://stackoverflow.com/questions/17174001/stop-pyzmq-receiver-by-keyboardinterrupt are to add, in sendExpression
Before result = self._omc.recv_string()
:
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
or a bit more fancy (and probably cleaner):
poller = zmq.Poller()
poller.register(self._omc, zmq.POLLIN)
try:
while True:
obj = dict(poller.poll(100)) # wait up to 100msec
if self._omc in obj and obj[self._omc] == zmq.POLLIN:
result = self._omc.recv_string()
break
except KeyboardInterrupt as e:
_msg = 'OMPython was interrupted while waiting for a reply'
logger.critical(_msg)
self.__del__()
raise KeyboardInterrupt(_msg)
which had the desired effect in some simple tests.
I don't know if this needs to be fixed in other places in the codebase, too.
MWE Python script for this problem (adapted from the example in the docs):
from OMPython import OMCSessionZMQ
omc = OMCSessionZMQ()
print(omc.sendExpression("getVersion()"))
print(omc.sendExpression("cd()"))
omc.sendExpression("loadModel(Modelica)")
omc.sendExpression("loadFile(getInstallationDirectoryPath() + \"/share/doc/omc/testmodels/BouncingBall.mo\")")
omc.sendExpression("instantiateModel(BouncingBall)")
print('simulating')
omc.sendExpression("simulate(BouncingBall, stopTime=3.0)")
# Pressing Ctrl-C here does not interrupt omc
# the script will not finish anymore
# you have to kill the Python process to get out of this
print('finished')