在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客户端那样实现它?我想要的原因是在收到消息后我想继续在当前环境中工作。
答案 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。