Skip to content

Commit

Permalink
Fix pymodbus-dev#640 asyncio client timeout fix
Browse files Browse the repository at this point in the history
  • Loading branch information
dhoomakethu committed Oct 17, 2021
1 parent 9097aa1 commit 1872ffb
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
version 2.5.3
----------------------------------------------------------
* Fix retries on tcp client failing randomly.
* Fix Asyncio client timeout arg not being used.

version 2.5.2
----------------------------------------------------------
Expand Down
33 changes: 19 additions & 14 deletions pymodbus/client/asynchronous/async_io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ class ReconnectingAsyncioModbusTcpClient(object):
#: Maximum delay in milli seconds before reconnect is attempted.
DELAY_MAX_MS = 1000 * 60 * 5

def __init__(self, protocol_class=None, loop=None):
def __init__(self, protocol_class=None, loop=None, **kwargs):
"""
Initialize ReconnectingAsyncioModbusTcpClient
:param protocol_class: Protocol used to talk to modbus device.
Expand All @@ -251,6 +251,7 @@ def __init__(self, protocol_class=None, loop=None):
self.connected = False
#: Reconnect delay in milli seconds.
self.delay_ms = self.DELAY_MIN_MS
self._proto_args = kwargs

def reset_delay(self):
"""
Expand Down Expand Up @@ -291,7 +292,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.factory = self
return protocol

Expand Down Expand Up @@ -350,7 +351,7 @@ def _reconnect(self):
class AsyncioModbusTcpClient(object):
"""Client to connect to modbus device over TCP/IP."""

def __init__(self, host=None, port=502, protocol_class=None, loop=None):
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
"""
Initializes Asyncio Modbus Tcp Client
:param host: Host IP address
Expand All @@ -369,6 +370,7 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None):
self.port = port

self.connected = False
self._proto_args = kwargs

def stop(self):
"""
Expand All @@ -384,7 +386,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.factory = self
return protocol

Expand Down Expand Up @@ -439,14 +441,14 @@ class ReconnectingAsyncioModbusTlsClient(ReconnectingAsyncioModbusTcpClient):
"""
Client to connect to modbus device repeatedly over TLS."
"""
def __init__(self, protocol_class=None, loop=None, framer=None):
def __init__(self, protocol_class=None, loop=None, framer=None, **kwargs):
"""
Initialize ReconnectingAsyncioModbusTcpClient
:param protocol_class: Protocol used to talk to modbus device.
:param loop: Event loop to use
"""
self.framer = framer
ReconnectingAsyncioModbusTcpClient.__init__(self, protocol_class, loop)
ReconnectingAsyncioModbusTcpClient.__init__(self, protocol_class, loop, **kwargs)

@asyncio.coroutine
def start(self, host, port=802, sslctx=None, server_hostname=None):
Expand Down Expand Up @@ -490,7 +492,7 @@ def _create_protocol(self):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class(framer=self.framer)
protocol = self.protocol_class(framer=self.framer, **self._proto_args)
protocol.transaction = FifoTransactionManager(self)
protocol.factory = self
return protocol
Expand All @@ -506,7 +508,7 @@ class ReconnectingAsyncioModbusUdpClient(object):
#: Maximum delay in milli seconds before reconnect is attempted.
DELAY_MAX_MS = 1000 * 60 * 5

def __init__(self, protocol_class=None, loop=None):
def __init__(self, protocol_class=None, loop=None, **kwargs):
"""
Initializes ReconnectingAsyncioModbusUdpClient
:param protocol_class: Protocol used to talk to modbus device.
Expand All @@ -523,6 +525,7 @@ def __init__(self, protocol_class=None, loop=None):
self.port = 0

self.connected = False
self._proto_args = kwargs
self.reset_delay()

def reset_delay(self):
Expand Down Expand Up @@ -572,7 +575,7 @@ def _create_protocol(self, host=None, port=0):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.host = host
protocol.port = port
protocol.factory = self
Expand Down Expand Up @@ -637,7 +640,7 @@ class AsyncioModbusUdpClient(object):
Client to connect to modbus device over UDP.
"""

def __init__(self, host=None, port=502, protocol_class=None, loop=None):
def __init__(self, host=None, port=502, protocol_class=None, loop=None, **kwargs):
"""
Initializes Asyncio Modbus UDP Client
:param host: Host IP address
Expand All @@ -656,6 +659,7 @@ def __init__(self, host=None, port=502, protocol_class=None, loop=None):
self.port = port

self.connected = False
self._proto_args = kwargs

def stop(self):
"""
Expand All @@ -674,7 +678,7 @@ def _create_protocol(self, host=None, port=0):
"""
Factory function to create initialized protocol instance.
"""
protocol = self.protocol_class()
protocol = self.protocol_class(**self._proto_args)
protocol.host = host
protocol.port = port
protocol.factory = self
Expand Down Expand Up @@ -842,7 +846,7 @@ def init_tcp_client(proto_cls, loop, host, port, **kwargs):
:return:
"""
client = ReconnectingAsyncioModbusTcpClient(protocol_class=proto_cls,
loop=loop)
loop=loop, **kwargs)
yield from client.start(host, port)
return client

Expand All @@ -863,7 +867,8 @@ def init_tls_client(proto_cls, loop, host, port, sslctx=None,
:return:
"""
client = ReconnectingAsyncioModbusTlsClient(protocol_class=proto_cls,
loop=loop, framer=framer)
loop=loop, framer=framer,
**kwargs)
yield from client.start(host, port, sslctx, server_hostname)
return client

Expand All @@ -880,6 +885,6 @@ def init_udp_client(proto_cls, loop, host, port, **kwargs):
:return:
"""
client = ReconnectingAsyncioModbusUdpClient(protocol_class=proto_cls,
loop=loop)
loop=loop, **kwargs)
yield from client.start(host, port)
return client
7 changes: 3 additions & 4 deletions pymodbus/client/asynchronous/factory/tcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ def io_loop_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
return protocol, future


def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
source_address=None, timeout=None, **kwargs):
def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
"""
Factory to create asyncio based asynchronous tcp clients
:param host: Host IP address
Expand All @@ -95,10 +94,10 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
proto_cls = kwargs.get("proto_cls", None)
if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tcp_client(proto_cls, loop, host, port)
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)
client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
cor = init_tcp_client(proto_cls, loop, host, port)
cor = init_tcp_client(proto_cls, loop, host, port, **kwargs)
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
client = future.result()

Expand Down
7 changes: 3 additions & 4 deletions pymodbus/client/asynchronous/factory/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
LOGGER = logging.getLogger(__name__)

def async_io_factory(host="127.0.0.1", port=Defaults.TLSPort, sslctx=None,
server_hostname=None, framer=None, source_address=None,
timeout=None, **kwargs):
server_hostname=None, framer=None, **kwargs):
"""
Factory to create asyncio based asynchronous tls clients
:param host: Host IP address
Expand All @@ -34,11 +33,11 @@ def async_io_factory(host="127.0.0.1", port=Defaults.TLSPort, sslctx=None,
if not loop.is_running():
asyncio.set_event_loop(loop)
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
framer, **kwargs)
client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
cor = init_tls_client(proto_cls, loop, host, port, sslctx, server_hostname,
framer)
framer, **kwargs)
future = asyncio.run_coroutine_threadsafe(cor, loop=loop)
client = future.result()

Expand Down
5 changes: 2 additions & 3 deletions pymodbus/client/asynchronous/factory/udp.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ def io_loop_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
return protocol, future


def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
source_address=None, timeout=None, **kwargs):
def async_io_factory(host="127.0.0.1", port=Defaults.Port, **kwargs):
"""
Factory to create asyncio based asynchronous udp clients
:param host: Host IP address
Expand All @@ -68,7 +67,7 @@ def async_io_factory(host="127.0.0.1", port=Defaults.Port, framer=None,
from pymodbus.client.asynchronous.async_io import init_udp_client
loop = kwargs.get("loop") or asyncio.get_event_loop()
proto_cls = kwargs.get("proto_cls", None)
cor = init_udp_client(proto_cls, loop, host, port)
cor = init_udp_client(proto_cls, loop, host, port, **kwargs)
if not loop.is_running():
client = loop.run_until_complete(asyncio.gather(cor))[0]
else:
Expand Down
2 changes: 1 addition & 1 deletion pymodbus/client/asynchronous/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, host="127.0.0.1", port=Defaults.Port, framer=None,
self.host = host
self.port = port
self.source_address = source_address or ("", 0)
self.timeout = timeout if timeout is not None else Defaults.Timeout
self._timeout = timeout if timeout is not None else Defaults.Timeout


class AsyncModbusSerialClientMixin(BaseAsyncModbusClient):
Expand Down

0 comments on commit 1872ffb

Please sign in to comment.