majek / puka

Puka - the opinionated RabbitMQ client
https://github.com/majek/puka
Other
182 stars 34 forks source link

AttributeError when heartbeat is enabled #49

Closed amackera closed 9 years ago

amackera commented 10 years ago

Hello all,

When I have heartbeat enabled in my client settings, I occasionally see AttributeError: 'NoneType' object has no attribute 'write' in my error logs.

Here's the stack trace:

Traceback (most recent call last):

 ... My Code ...

  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/client.py", line 19, in wrapper
    p = method(*args, **kwargs)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/machine.py", line 216, in queue_declare
    t = conn.promises.new(_queue_declare)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/promise.py", line 21, in new
    promise = Promise(self.conn, number, on_channel, **kwargs)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/promise.py", line 62, in __init__
    self.conn.channels.allocate(self, self._on_channel)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/channel.py", line 45, in allocate
    machine.channel_open(promise, on_channel)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/machine.py", line 207, in channel_open
    t.send_frames( spec.encode_channel_open('') )
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/promise.py", line 99, in send_frames
    self.conn._send_frames(self.channel.number, frames)
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/connection.py", line 185, in _send_frames
    for frame_type, payload in frames]) )
  File "/home/vagrant/.virtualenvs/thm/local/lib/python2.7/site-packages/puka/connection.py", line 177, in _send
    self.send_buf.write(data)
AttributeError: 'NoneType' object has no attribute 'write'

Looks to me like the way that heartbeats work in puka don't work very well with blocking architectures. A simple fix is to check if self.send_buf == None before writing, but I'm not sure what else that could break.

I've disabled heartbeats for now

amackera commented 10 years ago

As an update, after disabling heartbeats, my blocking implementation using puka has been performing perfectly.

majek commented 10 years ago

Yeah, support for heartbeats is a hack. I don't think that self.send_buf is ever Null except when the connection died, can you confirm it happens in your case?

Less ideal, but you can try using TCP keepalives (and delegate the work the operating system).