THRIFT-2883 TTwisted.py, during ConnectionLost processing: exceptions.RuntimeError: dictionary changed size during iteration
This closes #314 Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/dd02f552 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/dd02f552 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/dd02f552 Branch: refs/heads/master Commit: dd02f552835615f566ee811f96515e23d63c352b Parents: 9b35a7c Author: Robert Thille <[email protected]> Authored: Thu Jan 8 14:48:53 2015 -0800 Committer: Nobuaki Sukegawa <[email protected]> Committed: Thu Dec 24 02:11:17 2015 +0900 ---------------------------------------------------------------------- lib/py/src/transport/TTwisted.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/dd02f552/lib/py/src/transport/TTwisted.py ---------------------------------------------------------------------- diff --git a/lib/py/src/transport/TTwisted.py b/lib/py/src/transport/TTwisted.py index cabe345..6149a6c 100644 --- a/lib/py/src/transport/TTwisted.py +++ b/lib/py/src/transport/TTwisted.py @@ -29,7 +29,6 @@ from twisted.protocols import basic from twisted.web import server, resource, http from thrift.transport import TTransport -import six class TMessageSenderTransport(TTransport.TTransportBase): @@ -83,11 +82,18 @@ class ThriftClientProtocol(basic.Int32StringReceiver): self.started.callback(self.client) def connectionLost(self, reason=connectionDone): - for k, v in six.iteritems(self.client._reqs): + # the called errbacks can add items to our client's _reqs, + # so we need to use a tmp, and iterate until no more requests + # are added during errbacks + if self.client: tex = TTransport.TTransportException( type=TTransport.TTransportException.END_OF_FILE, - message='Connection closed') - v.errback(tex) + message='Connection closed (%s)' % reason) + while self.client._reqs: + _, v = self.client._reqs.popitem() + v.errback(tex) + del self.client._reqs + self.client = None def stringReceived(self, frame): tr = TTransport.TMemoryBuffer(frame)
