如何使用bunny RabbitMQ客户端阻止订阅?

时间:2013-05-21 09:15:53

标签: ruby jruby rabbitmq message-queue

在Java RabbitMQ客户端中我可以做(ruby中的代码):

 consumer = QueueingConsumer.new(channel);
 channel.basicConsume(queue_name, true, consumer);
 consumer.nextDelivery.getBody

然后第三行阻止线程直到消息到来。但是如何在Bunny客户端实现呢? 我只能使用块:

channel.queue('').bind(@x, :routing_key => rk).subscribe(block: true) do |_, _, payload|
  # do something
end

或非阻止pop:

delivery_info, properties, payload = q.pop

有没有办法像使用Bunny的jruby客户端那样实现它?我想要的原因是在收到消息后我想继续在当前环境中工作。

3 个答案:

答案 0 :(得分:2)

由于传递subscribe,对:block => true的调用已被阻止。如果您需要访问块外部的有效负载,您可以利用Ruby的范围规则:

the_payload = nil
queue = channel.queue('').bind(@x, :routing_key => rk)
queue.subscribe(block: true) do |delivery_info, _, payload|
  the_payload = payload
  channel.consumers[delivery_info.consumer_tag].cancel
end
# the_payload is now the one received in the block!

答案 1 :(得分:1)

Rob Harrop的回答确实取消了队列,但它并没有为我结束阻止。以下两者都使用ruby import re chars_to_remove = ['-dev.*','-rel.*'] # modify char to remove here def remove_char(s): return re.sub("({})$".format('|'.join(chars_to_remove)), '', s) branch1 = 'bt.lnx.2.1-dev.1.0' branch2 = 'bt.lnx.2.1-rel.1.0' branch3 = 'com-devices.lnx.1.0-dev' print remove_char(branch1) # 'bt.lnx.2.1' print remove_char(branch2) # 'bt.lnx.2.1' print remove_char(branch3) # should print com-devices.lnx.1.0

Queue

答案 2 :(得分:0)

我需要从队列中接收一条消息。兔子的Queue#pop是非阻塞的,没有选择等待的选项。我还需要支持超时,最终实现了这一点:

require "thread"

mutex = Mutex.new
var = ConditionVariable.new
payload = nil
consumer = queue.subscribe(block: false) do |_, _, x_payload|
  mutex.synchronize do
    payload = x_payload
    var.signal
  end
end

mutex.synchronize do
  deadline = Time.now + 10
  while payload.nil? && (remaining = deadline - Time.now) > 0
    var.wait(mutex, remaining)
  end
end

consumer.cancel
raise "timed out waiting for response" if payload.blank?

部分受https://spin.atomicobject.com/2017/06/28/queue-pop-with-timeout-fixed/启发

此代码尚未经过实战测试。它仅在处理单个消息时起作用。它可能无法大规模运行。我打算将所有这些复杂性隐藏在Bunny::Queue的猴子补丁中。调用者会看到一个简单的blocking_pop(timeout:) API。