agoragames / haigha

AMQP Python client
BSD 3-Clause "New" or "Revised" License
160 stars 41 forks source link

BasicClass.get return value is inconsistent in synchronous mode #83

Open vitaly-krugl opened 9 years ago

vitaly-krugl commented 9 years ago

In the implementation, self.channel.add_synchronous_cb(self._recv_get_response) only waits long enough for Basic.Get-ok/Get-empty method frame to arrive. So, if it gets Basic.Get-ok, but the Header and Content frames haven't arrived yet, it will return None, which is the same return value as when it gets Basic.Get-empty. So, quite often, there is actually a message on its way, but the BasicClass.get returns None, making the synchronous user think that the queue was empty, and that message will subsequently be "lost".

WGH- commented 5 years ago
class SyncWrapper(object):
    def __call__(self, *args, **kwargs):
        self._read = False
        self._result = self._cb(*args, **kwargs)

The problem here is self._cb might throw FrameUnderflow exception (easy to reproduce if you have large messages), but it happens after self._read is set to False. It causes while wrapper._read to terminate early, when wrapper._result is still None, and thus message will be lost.

I'm not sure how to fix it, though.