Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mitio/60448a8e9d4d9180fda63e22ba974b9c to your computer and use it in GitHub Desktop.
Save mitio/60448a8e9d4d9180fda63e22ba974b9c to your computer and use it in GitHub Desktop.
Demonstration of a race condition in RabbitMQ Bunny's Channel#wait_for_confirms (https://github.com/ruby-amqp/bunny/issues/424)
require 'thread'
require 'bunny'
operations_log = []
operations_log_mutex = Mutex.new
c = Bunny::Session.new
c.start
ch = c.create_channel
ch.confirm_select(proc { |tag, _, is_nack|
operation = "#{'n' if is_nack}ack of #{tag}"
operations_log_mutex.synchronize { operations_log << operation }
})
x = ch.default_exchange
q = ch.queue('', exclusive: true)
x.publish('msg', routing_key: q.name)
sleep 0.5 # Wait for the confirmation to be processed
# Artificially simulate a slower Ack
def (x.channel).handle_ack_or_nack(delivery_tag_before_offset, multiple, nack)
sleep 1
super
end
x.publish('msg', routing_key: q.name)
sleep 0.5
x.publish('msg', routing_key: q.name)
if x.wait_for_confirms
operation = 'all confirmed'
operations_log_mutex.synchronize { operations_log << operation }
end
# Wait a bit for the last confirm to arrive
sleep 2
# Check the operations log
#
# Expected: ["ack of 1", "ack of 2", "ack of 3", "all confirmed"]
# Actual: ["ack of 1", "all confirmed", "ack of 2", "ack of 3"]
p operations_log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment