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

Don't close/reopen tcp connection on single modbus message timeout #2346

Closed
wants to merge 2 commits into from

Conversation

ahcm-dev
Copy link
Contributor

I am connecting to a TCP to RTU modbus gateway which transparently passes on modbus requests to serial slaves on the downstream side. All works fine most of the time.

The application (home assistant) uses the AsyncModbusTCPClient to send periodic requests from a number of different threads to fetch data from different sensors on the different configured slaves.

If one slave malfunctions, or is powered off, a modbus request to it times out (though the gateway ack's the request at the TCP layer). This then causes the connection to be closed, and all the queued pending requests to the other slaves are failed. (Even though they would have succeeded if allowed to proceed).

While the connection quickly re-establishes again, the same thing happens as the polling function repolls the same unresponsive slave, and hence blocks successful activity from other healthy slaves.

I get good behaviour if in the tcp client we do not actually close the connection if the command to close with reconnect==True is sent. This relies on the tcp socket being relied upon to perform an unexpected close if the tcp timers time out.

@@ -86,8 +86,16 @@ def __init__( # pylint: disable=too-many-arguments
)

def close(self, reconnect: bool = False) -> None:
"""Close connection."""
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong, this method is called by the app when it wants to close the connection.

Why would you prevent the app from closing the connection ? Your problem is down in the transport layer.

Copy link
Contributor Author

@ahcm-dev ahcm-dev Sep 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how this can be resolved in the transport layer. The issue is the call to close() in async_execute() in client/base.py after too many retries of a particular request. The remote end will never respond to this request as it addresses an inactive slave. It will however respond to other requests, and closing the connection as a result causes these to fail too.

Maybe a better fix is in async_execute but it feels wrong to have tcp specific code in there. Any suggestions welcome!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the issue if the call to close in async_execute, then that would be a better place to fix the problem rather than prohibiting the app to close a connection.

Be aware your PR highlighted some old code, that should have been updated long time ago, it will be so very shortly.

@janiversen
Copy link
Collaborator

dev is updated.

@ahcm-dev ahcm-dev closed this Sep 30, 2024
@ahcm-dev ahcm-dev deleted the tcprtu-multi branch September 30, 2024 18:45
@ahcm-dev ahcm-dev restored the tcprtu-multi branch September 30, 2024 18:45
@janiversen
Copy link
Collaborator

janiversen commented Sep 30, 2024

??? I thought you had a problem, that you tried to solve ?

Your solution, as I pointed out, had serious side-effects and thus was not viable...but a working solution would be reviewed positively.

Please be aware the changes I made to the reconnect= parameter does NOT affect the close in case of timeout.

@ahcm-dev
Copy link
Contributor Author

ahcm-dev commented Sep 30, 2024 via email

@ahcm-dev
Copy link
Contributor Author

Closed in error - trying to reopen

@ahcm-dev
Copy link
Contributor Author

Pull request now updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants