Skip to content

Commit 5256c58

Browse files
authored
fix: Retry in more circumstances (#3)
1 parent 27a35be commit 5256c58

File tree

1 file changed

+23
-39
lines changed

1 file changed

+23
-39
lines changed

tcp_modbus_aio/client.py

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -467,45 +467,14 @@ async def send_modbus_message(
467467
time_budget_remaining -= conn_t()
468468

469469
# STEP THREE: WRITE OUR REQUEST
470-
try:
471-
writer.write(request_adu)
472-
473-
with catchtime() as write_t:
474-
await asyncio.wait_for(writer.drain(), time_budget_remaining)
475-
time_budget_remaining -= write_t()
476-
477-
if self.logger is not None:
478-
self.logger.debug(f"[{self}][send_modbus_message] wrote {msg_str}")
479-
480-
except OSError: # this includes timeout errors
481-
# Clear connection no matter what if we fail on the write
482-
# TODO: consider revisiting this to not do it on a timeouterror
483-
# (but Gru is scared about partial writes)
484-
485-
if self.logger is not None:
486-
self.logger.warning(
487-
f"[{self}][send_modbus_message] Failed to send data to modbus device for "
488-
f"request {msg_str}, clearing connection"
489-
)
490-
491-
self.clear_tcp_connection()
470+
writer.write(request_adu)
492471

493-
if retries > 0:
494-
if self.logger is not None:
495-
self.logger.warning(
496-
f"[{self}][send_modbus_message] Retrying {retries} more time(s) after failure to write"
497-
)
472+
with catchtime() as write_t:
473+
await asyncio.wait_for(writer.drain(), time_budget_remaining)
474+
time_budget_remaining -= write_t()
498475

499-
# release the lock before retrying (so we can re-get it)
500-
self._comms_lock.release()
501-
502-
return await self.send_modbus_message(
503-
request_function,
504-
timeout=timeout,
505-
retries=retries - 1,
506-
)
507-
508-
raise
476+
if self.logger is not None:
477+
self.logger.debug(f"[{self}][send_modbus_message] wrote {msg_str}")
509478

510479
try:
511480
# STEP FOUR: READ THE MBAP HEADER FROM THE RESPONSE (AND ANY JUNK)
@@ -559,15 +528,30 @@ async def send_modbus_message(
559528
raise ModbusCommunicationTimeoutError(
560529
f"Request {msg_str} timed out to {self.host}:{self.port}"
561530
) from e
562-
except OSError as e:
531+
except (OSError, EOFError) as e:
563532
if self.logger is not None:
564533
self.logger.warning(
565-
f"[{self}][send_modbus_message] OSError({type(e).__name__})({e}) while sending request {msg_str}, "
534+
f"[{self}][send_modbus_message] {type(e).__name__}({e}) while sending request {msg_str}, "
566535
"clearing connection"
567536
)
568537

569538
self.clear_tcp_connection()
570539

540+
if retries > 0:
541+
if self.logger is not None:
542+
self.logger.warning(
543+
f"[{self}][send_modbus_message] Retrying {retries} more time(s) after failure"
544+
)
545+
546+
# release the lock before retrying (so we can re-get it)
547+
self._comms_lock.release()
548+
549+
return await self.send_modbus_message(
550+
request_function,
551+
timeout=timeout,
552+
retries=retries - 1,
553+
)
554+
571555
raise ModbusCommunicationFailureError(
572556
f"Request {msg_str} failed to {self.host}:{self.port} ({type(e).__name__}({e}))"
573557
) from e

0 commit comments

Comments
 (0)