[rabbitmq-discuss] tx_commit() semantics with async connections (e.g Pika SelectConnection)
Gavin M. Roy
gmr at meetme.com
Fri Aug 17 20:38:50 BST 2012
On Fri, Aug 17, 2012 at 3:13 PM, Matt Pietrek <mpietrek at skytap.com> wrote:
> I've been drilling into an issue for a few days where my Pika channel is
> abruptly closed. I'm pretty sure I've found either:
> - A large gap in my understanding
> - A misuse of the Rabbit/Pika APIs
> Depending on your perspective, this seems the most likely, in that there
is not any logic in Pika for managing Tx. It lets you send the RPC calls
and leaves it to you to manage state outside of the connection/channel.
> - A serious bug in Pika.
> My original understanding about transactions is that calling tx_select()
> is a synchronous operation, and that when it returns, whatever actions
> you've sent to the broker are committed.
> However, in stepping through the Pika tx_commit() code, it seems like it
> all it does is add the Tx.Commit message to an outgoing buffer, and that
> the tx_commit() call returns without anything actually sent to the broker.
> (I've set breakpoints in the debugger at strategic points to verify this.)
This is correct, because pika is event-loop driven, it is putting the frame
in the output buffer and returning to you. The event loop will write the
data out as the operating system tells it it can You are correct that it is
not blocking on the Tx.Commit until the data is written over the socket.
> In my message handler, I'm writing a reply to the incoming message, using
> the same channel. What I'm seeing (verified via WireShark) is that the
> Tx.Commit message is followed by some number of Basic.Publish,
> Content-Header, and Content-Body records corresponding to my reply message
Your frames are sent in the order the methods are called.
> This violates the AMQP standard, which says that nothing should be sent to
> the broker after sending a Tx.Commit and before receiving a Tx.Commit-Ok
> reply. (If it helps understanding, my incoming message queue has a few
> messages in it already, so I see a series of incoming messages immediately
> after starting.)
You should add a callback for the Tx.Commit-Ok reply and then send your
messages. You are correct that Pika is not enforcing the behavior of
blocking until Tx.Commit-Ok.
You could open a 2nd channel and send your replies over that.
> I see that the tx_commit() method takes a callback method, but if I were
> to simply block in my message handler, waiting for the callback to be
> invoked, I'd deadlock because Pika's buffer processing code doesn't get a
> chance to run.
How are you blocking? If you're using any truly blocking method, it will
stop the event loop from running. Since you're on the async loop, I'd use a
timer and a state variable to toggle between the various states you're
trying to achieve.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the rabbitmq-discuss