我们已经使用daemon-kit创建了一个amqp worker,它应该接收一份工作,然后要求一份新工作,但不是在第一份工作完成之前。问题是,如果RabbitMQ队列中有一个,Daemon Kit会暂停工作并立即启动新工作。
是否有正式的方法可以在守护程序套件中强制执行一次性作业?或者我们如何实现这一目标?
这是我们启动amqp工作和处理作业的简短版本。当作业完成并返回结果时,它会将其发布回RabbitMQ服务器。
# Run an event-loop for processing
DaemonKit::AMQP.run do |connection|
connection.on_tcp_connection_loss do |client, settings|
DaemonKit.logger.debug("AMQP connection status changed: #{client.status}")
client.reconnect(false, 1)
end
amq = AMQP::Channel.new
amq.queue(engine_key).subscribe do |metadata,msg|
msg_decode = JSON.parse(msg)
job = REFxEngineRunnerAPI10.new msg_decode
result = job.run(metadata.correlation_id)
amq.queue( metadata.reply_to, :auto_delete => false)
xc = amq.default_exchange
xc.publish JSON.dump(result), :routing_key => metadata.reply_to, :correlation_id => metadata.correlation_id
end
end
更新
我发现这对我们有用:
DaemonKit::AMQP.run do |connection|
amq = AMQP::Channel.new(connection, prefetch: 1)
# I needs this extra line because I use RabbitMQ new than version 2.3.6
amq.qos(0, 1)
# be sure to add (:ack => true)
amq.queue(engine_key).subscribe(:ack => true) do |metadata,msg|
#### run long job one at a time
# Tell RabbitMQ I finished the job and I can now receive a new job
metadata.ack
end
end
答案 0 :(得分:1)
我在黑暗中捅了一下,因为这听起来确切地说明了协议的行为方式。但是,您可以使用 QoS 或预取来限制从代理发送给订阅者的消息数量,使用以下内容:
amq = AMQP::Channel.new(connection, prefetch: 1)
根据the example,这应该会给你你想要的行为。