summaryrefslogtreecommitdiff
path: root/packaging
diff options
context:
space:
mode:
authorMatthias Radestock <matthias@rabbitmq.com>2013-01-22 15:09:33 +0000
committerMatthias Radestock <matthias@rabbitmq.com>2013-01-22 15:09:33 +0000
commit6fdc8875d205347db625f978511c69c9eac4d980 (patch)
treeda2b996f4cf077131c0e187449ff7a883724d365 /packaging
parentb7751b9d8fa31ccc289a5708d9b0618581496b58 (diff)
downloadrabbitmq-server-git-6fdc8875d205347db625f978511c69c9eac4d980.tar.gz
prevent channel from sending anything after close/close_ok
The "we have sent a close/close_ok" state is indicated by state=closing. Well, not quite... The channel gets into the 'closing' state via notify_queues. That is called in three places: - 'terminate' - uninteresting since we don't send/do anything after that anyway - handle_exception when encountering a channel level error, i.e. when we send a channel.close - when receiving a 'channel.close'. Note that this isn't quite the same as sending a channel.close_ok. That in fact happens later, after a handshake with the reader. But for our purposes it's good enough. Certainly logically it is perfectly ok for us to stop sending things to the client once we have *seen* a 'close'. So how do we prevent sending in the 'closing' state? Firstly, we introduce a 'send' helper that replaces all rabbit_writer:send_command/2 invocations and is a no-op when state=closing. There is one notable exception - the sending of 'channel.close', which happens when state has already been set to 'closing'. rabbit_writer:send_command/2 isn't the only way to send commands to the writer though. The channel uses a few others: - send_command_sync - this is used to send channel.close_ok. We are in fact in the 'closing' state at that point and nevertheless must send that command (this is the tail end of the aforementioned handshake). So it's fine to leave this invocation as is. - send_command_and_notify - this is used to send messages with basic.deliver. We make that entire code a no-op in the no-op case, i.e. any messages sent by queues to the channel while it is 'closing' are simply dropped on the floor. This is TRTTD since it results in a minimum amount of work and is perfectly safe - no different to the channel terminating while those messages were in flight. - send_command/3 - this is used to send a basic.get_ok. That entire code - part of handle_method - is already guarded by a 'closing' state check that no-ops. It is also used to send basic.returns, which only happens in handling a basic.publish, which in turn is subject to the same handle_method guard. Finally, we add some optimisations to the 'confirm' and 'tx' code, so that all the logic for aggregating confirms and sending acks/nacks (or tx.commit / tx.commit failures) gets skipped when closing.
Diffstat (limited to 'packaging')
0 files changed, 0 insertions, 0 deletions