Skip to content

Conversation

@jadamcrain
Copy link
Member

• PR Title
Add configurable limit on consecutive client response timeouts

PR Description

Summary

  • introduce ClientOptions::max_response_timeouts so applications can cap consecutive Modbus response timeouts
  • track consecutive timeouts inside ClientLoop, resetting the counter after any non-timeout response
  • surface a new SessionError::MaxTimeouts so TCP/serial tasks drop and reconnect once the limit is reached

Fixes #144.

@gemini-code-assist
Copy link

Summary of Changes

Hello @jadamcrain, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the Modbus client's resilience by introducing a configurable mechanism to detect and recover from unresponsive connections. By allowing users to specify a limit on consecutive response timeouts, the system can proactively reset a session, preventing indefinite hangs and improving overall reliability, especially in scenarios where remote devices might silently fail or network issues lead to dropped packets without explicit connection termination signals.

Highlights

  • Configurable Timeout Limit: Introduced ClientOptions::max_response_timeouts to allow applications to set a maximum number of consecutive Modbus response timeouts before a session is reset.
  • Timeout Tracking: Implemented a TimeoutCounter within the ClientLoop to track consecutive timeouts, which resets upon any successful (non-timeout) response.
  • Session Error for Max Timeouts: Added a new SessionError::MaxTimeouts variant, which is triggered when the configured limit is reached, causing TCP/serial tasks to drop the current connection and attempt to reconnect.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a configurable limit on consecutive client response timeouts to enhance connection stability. The implementation for the TCP client is solid and includes good test coverage. However, the feature is currently not functional for serial clients as the configuration is hardcoded to be disabled. Additionally, there's a minor logic issue in the timeout counter that could cause problems in an extreme edge case. The review includes suggestions to address these points.

FrameWriter::rtu(),
FramedReader::rtu_response(),
decode,
None,

Choose a reason for hiding this comment

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

critical

The max_timeouts option is hardcoded to None for the serial client, which disables the new consecutive timeout limit feature. The PR description and the addition of SessionError::MaxTimeouts handling for serial connections suggest this feature should be available for serial clients as well. To fix this, the max_timeouts value should be configurable, likely by passing ClientOptions to SerialChannelTask::new similarly to how it's done for the TCP client.

match &mut self.state {
TimeoutCounterState::Disabled => Ok(()),
TimeoutCounterState::Enabled { current, max } => {
*current = current.wrapping_add(1);

Choose a reason for hiding this comment

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

medium

Using wrapping_add here could lead to unexpected behavior in an extreme edge case. If current reaches usize::MAX, it will wrap around to 0, effectively resetting the timeout counter instead of keeping it at its maximum value. This would prevent the MaxTimeouts error from being triggered if the number of timeouts is close to usize::MAX.

Using saturating_add would be safer and more correctly reflect the intent of capping the counter at a maximum value.

Suggested change
*current = current.wrapping_add(1);
*current = current.saturating_add(1);

@jadamcrain jadamcrain merged commit e2c162b into main Oct 16, 2025
26 checks passed
@jadamcrain jadamcrain deleted the feature/max-failed-requests branch October 16, 2025 22:36
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.

disabling ClientChannel without waiting for pending requests

2 participants