Festo-se / festo-edcon

festo-edcon is a python package which bundles modules to facilitate operation of Festo electric drives (currently via EtherNet/IP and Modbus) using PROFIDRIVE
MIT License
10 stars 1 forks source link

crash on shutdown #5

Closed simonvalfre closed 3 months ago

simonvalfre commented 4 months ago

Hello, When you call to shutdown() in com_modbus.py, the program crashes because it fails to join() the self.io_thread.

This prevents any attempt to shutdown gracefully. Is this the normal behavior ?

Or maybe is it possible to change a little the shutdown() method and add a try/catch ?

def shutdown(self):
        """Tries stop the communication thread and closes the modbus connection"""
        if hasattr(self, "io_thread"):
            if self.io_thread is not None:
                self.io_thread.stop()
                try:
                    self.io_thread.join()
                except:
                    Logging.logger.error(f"failed to join io thread")
                finally:
                    self.io_thread = None
        if hasattr(self, "modbus_client"):
            self.modbus_client.close()
elrosch commented 4 months ago

Interesting, I never experienced this on any of my PCs until now. I guess it may be related to some differences in timing when calling the destructors etc. I will have a thought and most probably go for your proposal

simonvalfre commented 4 months ago

Thanks ! I think you can reproduce easily just with trying to connect a non existing drive :

ERROR:Connection to (192.168.1.63, 502) failed: timed out
ERROR:Connection to (192.168.1.63, 502) failed: timed out
ERROR:Modbus client is not reachable
ERROR:Traceback (most recent call last):
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\edcon\edrive\com_modbus.py", line 157, in perform_io
    indata = self.modbus_client.read_holding_registers(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\pymodbus\client\mixin.py", line 107, in read_holding_registers
    return self.execute(
           ^^^^^^^^^^^^^
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\pymodbus\client\base.py", line 395, in execute
    raise ConnectionException(f"Failed to connect[{self!s}]")
pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Failed to connect[ModbusTcpClient 192.168.1.63:502]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\edcon\edrive\com_modbus.py", line 56, in run
    self.perform_io()
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\edcon\edrive\com_modbus.py", line 174, in perform_io
    self.shutdown()
  File "C:\projet\tbe_ao\tbe_ao\.venv\Lib\site-packages\edcon\edrive\com_modbus.py", line 108, in shutdown
    self.io_thread.join()
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.11_3.11.2544.0_x64__qbz5n2kfra8p0\Lib\threading.py", line 1116, in join
    raise RuntimeError("cannot join current thread")
RuntimeError: cannot join current thread
elrosch commented 3 months ago

Not able to reproduce this either. Most probably due to the variation of timing of the executing machine. I will try to play around a bit

elrosch commented 3 months ago

Just removed the .join() calls. Apparently they are not needed.