astrorafael / twisted-mqtt

MQTT Client protocol for Twisted.
MIT License
30 stars 11 forks source link

Fix Python 3.x related dictionary-changed-size-during-iteration error #8

Closed gandy92 closed 6 years ago

gandy92 commented 6 years ago

This pull-request fixes an error that occurs only with Python 3.x: Every now and then the pub/sub service would fail keeping the reactor without anything to do:

2017-11-20T03:28:19+0100 [MQTTProtocol,client] Unhandled Error
        Traceback (most recent call last):
          File "/home/..../mqtt-process.py", line 201, in main
            reactor.run()
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/base.py", line 1199, in run
            self.mainLoop()
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/base.py", line 1211, in mainLoop
            self.doIteration(t)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/epollreactor.py", line 235, in doPoll
            log.callWithLogger(selectable, _drdw, selectable, fd, event)
        --- <exception caught here> ---
          File "/usr/local/lib/python3.5/dist-packages/twisted/python/log.py", line 103, in callWithLogger
            return callWithContext({"system": lp}, func, *args, **kw)
          File "/usr/local/lib/python3.5/dist-packages/twisted/python/log.py", line 86, in callWithContext
            return context.call({ILogContext: newCtx}, func, *args, **kw)
          File "/usr/local/lib/python3.5/dist-packages/twisted/python/context.py", line 118, in callWithContext
            return self.currentContext().callWithContext(ctx, func, *args, **kw)
          File "/usr/local/lib/python3.5/dist-packages/twisted/python/context.py", line 81, in callWithContext
            return func(*args,**kw)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/posixbase.py", line 610, in _doReadOrWrite
            self._disconnectSelectable(selectable, why, inRead)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/posixbase.py", line 252, in _disconnectSelectable
            selectable.readConnectionLost(f)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/tcp.py", line 272, in readConnectionLost
            self.connectionLost(reason)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/tcp.py", line 478, in connectionLost
            self._commonConnection.connectionLost(self, reason)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/tcp.py", line 292, in connectionLost
            protocol.connectionLost(reason)
          File "/usr/local/lib/python3.5/dist-packages/twisted/internet/endpoints.py", line 130, in connectionLost
            return self._wrappedProtocol.connectionLost(reason)
          File "/usr/local/lib/python3.5/dist-packages/twisted/application/internet.py", line 435, in connectionLost
            return self._protocol.connectionLost(reason)
          File "/usr/local/lib/python3.5/dist-packages/mqtt/client/base.py", line 520, in connectionLost
            self.doConnectionLost(reason)
          File "/usr/local/lib/python3.5/dist-packages/mqtt/client/pubsubs.py", line 675, in doConnectionLost
            for k in self.factory.windowPublish[self.addr].keys():
        builtins.RuntimeError: dictionary changed size during iteration

2017-11-20T03:28:19+0100 [twisted.internet.defer#critical] Unhandled error in Deferred:
2017-11-20T03:28:19+0100 [twisted.internet.defer#critical] 
        Traceback (most recent call last):
        Failure: twisted.internet.error.ConnectionDone: Connection was closed cleanly.

As pointed out in https://stackoverflow.com/a/11941855 the bugfix works for both Python 2 and 3.

astrorafael commented 6 years ago

Thanks for fixing this ! I use python 2.7 for the time being