Daemon-kit一次处理一个amqp作业

时间:2015-09-16 06:58:44

标签: ruby rabbitmq daemon amqp

我们已经使用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

1 个答案:

答案 0 :(得分:1)

我在黑暗中捅了一下,因为这听起来确切地说明了协议的行为方式。但是,您可以使用 QoS 预取来限制从代理发送给订阅者的消息数量,使用以下内容:

amq = AMQP::Channel.new(connection, prefetch: 1)

根据the example,这应该会给你你想要的行为。