我填满队列,检查它有正确的任务数量,然后将并行设置的工作人员设置为prefetch(1)
,以确保每个任务一次只完成一项任务。
我希望每个工作人员都能完成其任务,发送手动确认,并在有更多工作要做的情况下继续工作。
如果没有更多的工作,即队列为空,我希望工作脚本完成并return(0)
。
所以,这就是我现在所拥有的:
require 'bunny'
connection = Bunny.new("amqp://my_conn")
connection.start
channel = connection.create_channel
queue = channel.queue('my_queue_name')
channel.prefetch(1)
puts ' [*] Waiting for messages.'
begin
payload = 'init'
until queue.message_count == 0
puts "worker working queue length is #{queue.message_count}"
_delivery_info, _properties, payload = queue.pop
unless payload.nil?
puts " [x] Received #{payload}"
raise "payload invalid" unless payload[/cucumber/]
begin
do_stuff(payload)
rescue => e
puts "Error running #{payload}: #{e.backtrace.join('\n')}"
#failing stuff
end
end
puts " [x] Done with #{payload}"
end
puts "done with queue"
connection.close
exit(0)
ensure
connection.close
end
当队列为空时,我仍要确保已完成。这是RabbitMQ网站... https://www.rabbitmq.com/tutorials/tutorial-two-ruby.html中的示例。它有许多我们想要的工作队列,最重要的是手动确认。但是它不会停止运行,我需要在队列完成后以编程方式进行:
#!/usr/bin/env ruby
require 'bunny'
connection = Bunny.new(automatically_recover: false)
connection.start
channel = connection.create_channel
queue = channel.queue('task_queue', durable: true)
channel.prefetch(1)
puts ' [*] Waiting for messages. To exit press CTRL+C'
begin
queue.subscribe(manual_ack: true, block: true) do |delivery_info, _properties, body|
puts " [x] Received '#{body}'"
# imitate some work
sleep body.count('.').to_i
puts ' [x] Done'
channel.ack(delivery_info.delivery_tag)
end
rescue Interrupt => _
connection.close
end
当队列已完全工作(总数为0,未确认的为0)时,该脚本如何适应退出?
答案 0 :(得分:0)
据我了解,如果RabbitMQ队列中没有待处理的消息,您希望您的订阅者结束。
鉴于您的第二个脚本,您可以避免传递block: true
,并且在没有更多数据要处理时将不返回任何内容。在这种情况下,您可以退出程序。
您可以在文档中看到:http://rubybunny.info/articles/queues.html#blocking_or_nonblocking_behavior
默认情况下,它是非阻塞的。