メッセージを未確認状態から準備完了状態にプッシュする方法
概要
私の質問は以前に尋ねられた質問と似ていますが、答えは見つかりません。Web サービスと呼ばれるアクションを処理したいコンシューマーがありますが、この Web サービスが何らかの理由で応答しない場合は、コンシューマは RabbitMQ のメッセージを処理しませんが、後で処理するようにエンコールします。私のコンシューマは次のとおりです。
require File.expand_path('../config/environment.rb', __FILE__)
conn=Rabbit.connect
conn.start
ch = conn.create_channel
x = ch.exchange("d_notification_ex", :type=> "x-delayed-message", :arguments=> { "x-delayed-type" => "direct"})
q = ch.queue("d_notification_q", :durable =>true)
q.bind(x)
p 'Wait ....'
q.subscribe(:manual_ack => true, :block => true) do |delivery_info, properties, body|
datos=JSON.parse(body)
if datos['status']=='request'
#I call a web service and process the json
result=Notification.send_payment_notification(datos.to_json)
else
#I call a web service and process the body
result=Notification.send_payment_notification(body)
end
#if the call to the web service, the web server is off the result will be equal to nil
#therefore, he did not notify RabbitMQ, but he puts the message in UNACKED status
# and does not process it later, when I want him to keep it in the queue and evaluate it afterwards.
unless result.nil?
ch.ack(delivery_info.delivery_tag)
end
end
RabbitMQのイメージ、
ステートメントには、次のような方法があります: c hack (delivery_info.delivery_tag)、これにより、キューの要素を削除する代わりに、後で処理できるようになります。何かアイデアはありますか?ありがとう
解決策
「コンシューマー内のプロデューサー」というスタイルでデータをキューに送り返すことにしました。コードは次のようになります。
if result.eql? 'ok'
ch.ack(delivery_info.delivery_tag)
else
if(datos['count'] < 5)
datos['count'] += 1
d_time=1000
x.publish(datos.to_json, :persistent => true, :headers=>{"x-delay" => d_time})
end
end
ただし、JSON 属性にもう 1 つの属性を含める必要がありました。Count!無限サイクルに留まらないように。