njouanin / hbmqtt

MQTT client/broker using Python asynchronous I/O
MIT License
795 stars 188 forks source link

How to correctly disconnect & clean up #216

Open patrickjane opened 4 years ago

patrickjane commented 4 years ago

I hope I am not duplicating #106 here, but while this isse has been resolved long time ago, I still get the mentioned error when I try to gracefully shutdown my program.

In a nutshell:

def main():
    loop = asyncio.get_event_loop()
    mq = mqtt.Mqtt()  # my wrapper class

    try:
        loop.run_until_complete(mq.connect())
    except KeyboardInterrupt:
        pass
    except Exception as e:
        self.log.error("Got exception: {}".format(e))
    finally:
        loop.run_until_complete(mq.disconnect())
        loop.close()

class Mqtt

59    async def connect(self):
60        self.client = MQTTClient()
61
62        await self.client.connect(uri)
63        await self.client.subscribe([(self.topic, QOS_0)])
64
65        while True:
66            try:
67                message = await self.client.deliver_message()
68                await ... # handle message coro
69            except ClientException as e:
70                self.log.error("MQTT Client exception: {}".format(e))
71                break
72            except Exception as e:
73                self.log.error("MQTT exception: {}".format(e))
74                break

80    async def disconnect(self):
81        await self.client.unsubscribe([self.topic])
82        await self.client.disconnect()

Now when I do CTRL+C, it should interrupt the loop execution and call the stop-logic in the finally:-block, which will ultimately call unsubscribe/disconnect.

However I get the following exception:

future: <Task finished coro=<Mqtt.connect() done, defined at /Users/s710/Development/myapp/mqtt.py:59> exception=IndexError('pop from an empty deque')>
Traceback (most recent call last):
  File "/Users/s710/Development/myapp/mqtt.py", line 67, in connect
    message = await self.client.deliver_message()
  File "/Users/s710/Development/myapp/venv/lib/python3.7/site-packages/hbmqtt/client.py", line 356, in deliver_message
    self.client_tasks.pop()
IndexError: pop from an empty deque

Do I have some general misconception here (I am still new to asyncio programming), or can this error be ignored?