OMPython icon indicating copy to clipboard operation
OMPython copied to clipboard

Possible for ZMQ freezes when receiving data

Open JKRT opened this issue 5 years ago • 3 comments

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

JKRT avatar Jun 12 '19 13:06 JKRT

@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)

JKRT avatar Sep 12 '19 13:09 JKRT

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.

bilderbuchi avatar Jul 06 '22 08:07 bilderbuchi

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')

bilderbuchi avatar Jul 06 '22 10:07 bilderbuchi