2017-05-19 3 views
1

Ich habe eine Rails-App, die manchmal Nachrichten an eine RabbitMQ-Warteschlange mit dem Edelstein "Bunny" veröffentlicht. Hier ist das Setup:Ist es möglich, Bunny :: Exchange von verzögerten Job zu veröffentlichen?

# config/initializers/bunny.rb 
$mq_connection = Bunny.new 
$mq_connection.start 
$mq_channel = $mq_connection.create_channel 

überall in der app, die ich dann anrufen:

exchange = $mq_channel.default_exchange 
exchange.publish(msg.to_json, persistent: true, routing_key: '...') 

Dies funktioniert gut, wenn ich es aus der App heraus anrufen, oder von der Konsole, aber es doesen't Arbeit wenn es von einem DelayedJob Job aufgerufen wird. Es wird keine Ausnahme ausgelöst, aber die Nachricht wird nicht gesendet.

mit einem Singleton Versuch:

class RabbitMq 
    include Singleton 

    attr_accessor :connection, :channel 

    def exchange 
    channel.default_exchange 
    end 

    def setup 
    self.connection = Bunny.new 
    self.connection.start 
    self.channel = connection.create_channel 
    end 

end 

Und ich rufe das Setup:

Es ist wie globale Variablen wie $mq_channel sah nicht durch DelayedJob, so habe ich ein Singleton-Modell zu speichern, es gefunden werden konnte von meinem initializer:

# config/initializers/bunny.rb 
RabbitMq.instance.setup 

Aber das auch nicht funktioniert. Der Job wird ohne Fehler beendet, aber es wird nichts veröffentlicht.

Irgendeine Idee, wie man das macht? Es sollte ziemlich üblich sein, Nachrichten an RabbitMQ von einem Hintergrund-Arbeiter wie DJ zu veröffentlichen.

Antwort

1

Hier ist, wie ich es tun:

class Messaging::Publisher 

    class << self 

    def publish(message) 
     new(message).publish 
    end 

    end # Class Methods 

    #========================================================================= 
    # Instance Methods  
    #========================================================================= 

    def initialize(message) 
     @message = message 
    end 

    def publish 
     connection = Bunny.new(ENV['CLOUDAMQP_URL']) 
     connection.start 
     channel = connection.create_channel 
     queue_name = "#{ENV['app_name']}.#{message.keys.first.to_s.pluralize}_queue" 
     queue = channel.queue(queue_name, durable: true) 
     channel.default_exchange.publish(message.to_json, :routing_key => queue.name) 
     channel.close 
     connection.stop 
     true 
    end 

    private 

    def message() @message end 

end 

ich diese beide rufen aus meiner app (synchron) und von Hintergrundjobs (asynchron). Etwas wie folgt aus:

class ServiceRequests::CreateManager < ServiceRequests::ManagerBase 

    class << self 

    private 

    end # Class Methods 

    #========================================================================= 
    # Instance Methods 
    #========================================================================= 

    def manage 
     Messaging::Publisher.publish service_request_message 
    end 

    private 

    def service_request_message 
     { 
     service_request: { 
      provider: { 
      name: "Foo::Bar" 
      }, 
      params: { 
      baz: 'qux' 
      } 
     } 
     } 
    end 

end 
+1

Es funktioniert in der Tat, wenn ich eine neue Verbindung jedes Mal muss ich erstellen eine Nachricht veröffentlichen. Vielen Dank! – jibai31

Verwandte Themen