diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2023-09-21 14:42:44 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2023-09-21 14:52:55 -0400 |
commit | e9bf2d4c5c02e8fbf1130928bf08f8de37e6ee79 (patch) | |
tree | 85a1d61b1e0d83289b2cebb33e7b8fc4cf02a875 /klippy | |
parent | 8ef0f7d7e3d3b2ac7bc1e80ed3295ceca6bba4e7 (diff) | |
download | kutter-e9bf2d4c5c02e8fbf1130928bf08f8de37e6ee79.tar.gz kutter-e9bf2d4c5c02e8fbf1130928bf08f8de37e6ee79.tar.xz kutter-e9bf2d4c5c02e8fbf1130928bf08f8de37e6ee79.zip |
mcu: Enhance RetryAsyncCommand to handle low-level retransmits
The RetryAsyncCommand code needs to ensure that any response messages
are not from a previous (unrelated) query. To do that it compares the
'#sent_time' from potential responses to ensure they are not from a
previous session. However, if there are any low-level serial
retransmits then the low-level code sets the '#sent_time' to zero (to
indicate that the query send time is not strictly known). That could
result in a valid response not being accepted by RetryAsyncCommand.
If a low-level connection is experiencing a small amount of periodic
retransmits it could result in multiple high-level retry attempts
failing to the point that there is a user-facing error. This could
result in "Timeout on wait for 'tmcuart_response' response" errors.
Fix by accepting responses even if there is a low-level retransmit
once the code can confirm that there can be no previous query still in
progress.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Diffstat (limited to 'klippy')
-rw-r--r-- | klippy/mcu.py | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/klippy/mcu.py b/klippy/mcu.py index 76c70506..68179bdd 100644 --- a/klippy/mcu.py +++ b/klippy/mcu.py @@ -25,14 +25,16 @@ class RetryAsyncCommand: self.reactor = serial.get_reactor() self.completion = self.reactor.completion() self.min_query_time = self.reactor.monotonic() + self.need_response = True self.serial.register_response(self.handle_callback, name, oid) def handle_callback(self, params): - if params['#sent_time'] >= self.min_query_time: - self.min_query_time = self.reactor.NEVER + if self.need_response and params['#sent_time'] >= self.min_query_time: + self.need_response = False self.reactor.async_complete(self.completion, params) def get_response(self, cmds, cmd_queue, minclock=0, reqclock=0): cmd, = cmds self.serial.raw_send_wait_ack(cmd, minclock, reqclock, cmd_queue) + self.min_query_time = 0. first_query_time = query_time = self.reactor.monotonic() while 1: params = self.completion.wait(query_time + self.RETRY_TIME) |