提交 231b7fd5 编写于 作者: P Pierre Fersing

Add exponential reconnection delay

上级 cbf1da91
......@@ -14,6 +14,7 @@ v1.3.x - 2017-xx-xx
- Allow arbitrary Websocket headers and path.
Closes #169.
- Fix issue with large inbound payload over Websocket. Closes #107.
- Add exponential delay for reconnection. Closes #195.
- Move unit tests to pytest (#164) and tox (#187)
- Add support for standard Python logging. Closes #95.
......
......@@ -383,6 +383,23 @@ retain
Raises a ``ValueError`` if ``qos`` is not 0, 1 or 2, or if ``topic`` is
``None`` or has zero string length.
reconnect_delay_set
'''''''''''''''''''
::
reconnect_delay_set(min_delay=1, max_delay=120)
The client will automatically retry connection. Between each attempt
it will wait a number of seconds between ``min_delay`` and ``max_delay``.
When the connection is lost, initially the reconnection attempt is delayed of
``min_delay`` seconds. It's doubled between subsequent attempt up to ``max_delay``.
The delay is reset to ``min_delay`` when the connection complete (e.g. the CONNACK is
received, not just the TCP connection is established).
Connect / reconnect / disconnect
````````````````````````````````
......
......@@ -516,6 +516,9 @@ class Client(object):
self._current_out_packet = None
self._last_msg_in = time_func()
self._last_msg_out = time_func()
self._reconnect_min_delay = 1
self._reconnect_max_delay = 120
self._reconnect_delay = None
self._ping_t = 0
self._last_mid = 0
self._state = mqtt_cs_new
......@@ -541,6 +544,7 @@ class Client(object):
self._msgtime_mutex = threading.Lock()
self._out_message_mutex = threading.RLock()
self._in_message_mutex = threading.Lock()
self._reconnect_delay_mutex = threading.Lock()
self._thread = None
self._thread_terminate = False
self._ssl = False
......@@ -814,6 +818,19 @@ class Client(object):
self._state = mqtt_cs_connect_async
def reconnect_delay_set(self, min_delay=1, max_delay=120):
""" Configure the exponential reconnect delay
When connection is lost, wait initially min_delay seconds and
double this time every attempt. The wait is capped at max_delay.
Once the client is fully connected (e.g. not only TCP socket, but
received a success CONNACK), the wait timer is reset to min_delay.
"""
with self._reconnect_delay_mutex:
self._reconnect_min_delay = min_delay
self._reconnect_max_delay = min_delay
self._reconnect_delay = None
def reconnect(self):
"""Reconnect the client after a disconnect. Can only be called after
connect()/connect_async()."""
......@@ -1433,7 +1450,7 @@ class Client(object):
if not retry_first_connection:
raise
self._easy_log(MQTT_LOG_DEBUG, "Connection failed, retrying")
time.sleep(1)
self._reconnect_wait()
else:
break
......@@ -1460,7 +1477,7 @@ class Client(object):
if should_exit():
run = False
else:
time.sleep(1)
self._reconnect_wait()
if should_exit():
run = False
......@@ -2310,6 +2327,7 @@ class Client(object):
if result == 0:
self._state = mqtt_cs_connected
self._reconnect_delay = None
self._easy_log(MQTT_LOG_DEBUG, "Received CONNACK (%s, %s)", flags, result)
......@@ -2585,6 +2603,28 @@ class Client(object):
def _thread_main(self):
self.loop_forever(retry_first_connection=True)
def _reconnect_wait(self):
# See reconnect_delay_set for details
now = time_func()
with self._reconnect_delay_mutex:
if self._reconnect_delay is None:
self._reconnect_delay = self._reconnect_min_delay
else:
self._reconnect_delay = min(
self._reconnect_delay * 2,
self._reconnect_max_delay,
)
target_time = now + self._reconnect_delay
remaining = target_time - now
while (self._state != mqtt_cs_disconnecting
and not self._thread_terminate
and remaining > 0):
time.sleep(min(remaining, 1))
remaining = target_time - time_func()
# Compatibility class for easy porting from mosquitto.py.
class Mosquitto(Client):
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册