Skip to content

Commit

Permalink
Handle unexpected errors while reconnecting (#119)
Browse files Browse the repository at this point in the history
When we reconnect we are doing an explicit disconnect, this can fail and if
we don't handle possible exceptions we won't reconnect (even when it's
possible to do so)

A way to reproduce this easily is killing the connection with `ss -K`
(linux only)
  • Loading branch information
blaxter authored Nov 23, 2020
1 parent 75969de commit 5447f1c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
5 changes: 4 additions & 1 deletion gmqtt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,10 @@ async def reconnect(self, delay=False):
return
# stopping auto-reconnects during reconnect procedure is important, better do not touch :(
self._temporatily_stop_reconnect()
await self._disconnect()
try:
await self._disconnect()
except:
logger.info('[RECONNECT] ignored error while disconnecting, trying to reconnect anyway')
if delay:
await asyncio.sleep(self._config['reconnect_delay'])
try:
Expand Down
20 changes: 20 additions & 0 deletions tests/test_mqtt5.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
import os
import time
from unittest import mock

import pytest

Expand Down Expand Up @@ -462,3 +463,22 @@ async def test_basic_ssl(init_clients):
aclient.publish(TOPICS[0], b"qos 2", 2)
await asyncio.sleep(1)
assert len(callback2.messages) == 3


@pytest.mark.asyncio
async def test_reconnection_with_failure(init_clients):
aclient, callback, bclient, callback2 = init_clients
aclient.set_config({'reconnect_retries': -1, 'reconnect_delay': 0})
await aclient.connect(host=host, port=port)
await bclient.connect(host=host, port=port)

bclient.subscribe(TOPICS[0])

with mock.patch.object(aclient, '_disconnect') as disconnect_mock:
disconnect_mock.side_effect = ConnectionAbortedError("error")
await aclient.reconnect()

# Check aclient is still working after reconnection
aclient.publish(TOPICS[0], b"test")
await asyncio.sleep(1)
assert len(callback2.messages) == 1

0 comments on commit 5447f1c

Please sign in to comment.