Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signal handlers to stop in shutdown(). #81

Merged
merged 1 commit into from
Sep 26, 2015
Merged

Conversation

estan
Copy link
Contributor

@estan estan commented May 3, 2015

ModbusTcpServer currently overrides server_close to signal its request handlers to stop processing, but doesn't do the same with shutdown. The result is that when running the server using serve_forever in another thread, and then trying to signal it to stop by calling shutdown from the main thread, then the shutdown call will block forever if there are ongoing requests, since the handler threads never finishes.

Minimal Example

server.py

#!/usr/bin/env python
from pymodbus.server.sync import ModbusTcpServer
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

from threading import Thread
from time import sleep

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

context = ModbusServerContext(slaves=ModbusSlaveContext())
server = ModbusTcpServer(context=context, address=("localhost", 5020))

thread = Thread(target=server.serve_forever)
thread.start()

try:
    while thread.is_alive():
        sleep(1)
except KeyboardInterrupt:
    print("Exiting...")
    server.shutdown()
    thread.join()

client.py

#!/usr/bin/env python
from pymodbus.client.sync import ModbusTcpClient
from time import sleep

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

try:
    client = ModbusTcpClient("localhost", port=5020)
    client.connect()
    while True:
        client.write_coil(1, True)
        client.read_coils(1, 1)
        sleep(1)
except KeyboardInterrupt:
    client.close()

Instructions

  1. Run server.py.
  2. Run client.py.
  3. Press Ctrl+C in the terminal running server.py.
  4. The server does not stop.

With this patch, ModbusTcpServer overrides shutdown to signal all handlers to stop before calling the base class implementation. The server now exits as expected.

Note that the above was just an example, where threading was not necessary. In my real use case, I had a Qt application that ran serve_forever in a separate thread, to avoid blocking the Qt event loop.

bashwork added a commit that referenced this pull request Sep 26, 2015
Signal handlers to stop in shutdown().
@bashwork bashwork merged commit 175abc9 into pymodbus-dev:master Sep 26, 2015
dhoomakethu pushed a commit that referenced this pull request May 16, 2017
Signal handlers to stop in shutdown().
ccatterina pushed a commit to ccatterina/pymodbus that referenced this pull request Apr 17, 2018
Signal handlers to stop in shutdown().
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants