Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

channel.build_inbound_messages with break_on_empty=True randomly breaks loop #63

Closed
TomGudman opened this issue Oct 17, 2018 · 4 comments
Labels
Milestone

Comments

@TomGudman
Copy link

TomGudman commented Oct 17, 2018

Hi,

  • Context: I am trying to empty a queue from time to time and exit once empty. (e.g: queue has 10k messages)
  • Version: 2.4.2 / python3
  • Issue: When break_on_empty=True in channel.build_inbound_messages is set, it randomly gets between 1 to 15 messages before exiting whereas there are still thousands of messages in the queue. The queue contains 10k messages, no publishers, the queue is still. Each run of the below code would get a random amount of messages and then exit. Without break_on_empty, it gets the 10k messages in less than 10sec but then it remains connected which I don't want.

An edited version of the code I used.

from amqpstorm import Connection
queue='simple_queue'
server='127.0.0.1'
username = password = 'guest'

count=0
with Connection(server, username, password) as connection:
  with connection.channel() as channel:
    #channel.queue.declare(queue)
    channel.basic.qos(100)
    channel.basic.consume(queue=queue, no_ack=False)
    for message in channel.build_inbound_messages(break_on_empty=True):
      if message:
         count += 1
         message.ack()

ref: https://www.amqpstorm.io/api/channel.html#amqpstorm.Channel.build_inbound_messages

Thanks for this library.

@TomGudman TomGudman changed the title channel.build_inbound_messages withbreak_on_empty=True randomly breaks loop channel.build_inbound_messages with break_on_empty=True randomly breaks loop Oct 17, 2018
@eandersson eandersson added the bug label Oct 17, 2018
@eandersson eandersson added this to the 2.4.3 milestone Oct 17, 2018
@eandersson
Copy link
Owner

eandersson commented Oct 17, 2018

Thanks for the report @TomGudman . This does indeed look like a bug.

I might have to update the documentation for break_on_empty, as there is no guarantee that it will actually consume until the queue is actually empty. If the network or RabbitMQ for some reason is delivering new messages slow, it may kill the for loop. I added an extra sleep to help compensate for this, but ideally you probably want to check the queue length once done to verify.

I'll probably need to follow up with some test adjustments before I can release this, but if you have time, please test the above patch.

eandersson added a commit that referenced this issue Oct 18, 2018
* Properly wait until the inbound queue is empty #63
* Preparing new release
* Remove unnecessary continue
@eandersson
Copy link
Owner

eandersson commented Oct 22, 2018

So even with the bug fix this is going to be an issue. However, if you set no_ack to True you will be practically guaranteed to empty the queue, but with no_ack=True and QoS you will probably not have the same luck.

@TomGudman
Copy link
Author

TomGudman commented Oct 22, 2018 via email

@eandersson eandersson mentioned this issue Nov 4, 2018
@eandersson
Copy link
Owner

I would recommend this example.
https://github.com/eandersson/amqpstorm/blob/c64a687f738cefd6f9461f487e76a3920d0f652c/examples/consume_queue_until_empty.py

Pretty sure this is the best practice.

@eandersson eandersson modified the milestones: 2.4.3, 2.5.0 Nov 25, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants