rosetta_queue 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +38 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.rdoc +11 -0
- data/Rakefile +39 -0
- data/VERSION.yml +4 -0
- data/cucumber.yml +1 -0
- data/examples/sample_amqp_consumer.rb +45 -0
- data/examples/sample_amqp_fanout_consumer.rb +52 -0
- data/examples/sample_amqp_fanout_producer.rb +18 -0
- data/examples/sample_amqp_producer.rb +16 -0
- data/features/filtering.feature +31 -0
- data/features/messaging.feature +48 -0
- data/features/step_definitions/common_messaging_steps.rb +82 -0
- data/features/step_definitions/filtering_steps.rb +17 -0
- data/features/step_definitions/point_to_point_steps.rb +22 -0
- data/features/step_definitions/publish_subscribe_steps.rb +25 -0
- data/features/support/env.rb +25 -0
- data/features/support/sample_consumers.rb +29 -0
- data/lib/rosetta_queue.rb +23 -0
- data/lib/rosetta_queue/adapter.rb +39 -0
- data/lib/rosetta_queue/adapters/amqp.rb +48 -0
- data/lib/rosetta_queue/adapters/amqp_evented.rb +132 -0
- data/lib/rosetta_queue/adapters/amqp_synch.rb +123 -0
- data/lib/rosetta_queue/adapters/base.rb +27 -0
- data/lib/rosetta_queue/adapters/beanstalk.rb +56 -0
- data/lib/rosetta_queue/adapters/fake.rb +26 -0
- data/lib/rosetta_queue/adapters/null.rb +57 -0
- data/lib/rosetta_queue/adapters/stomp.rb +88 -0
- data/lib/rosetta_queue/base.rb +15 -0
- data/lib/rosetta_queue/consumer.rb +30 -0
- data/lib/rosetta_queue/consumer_managers/base.rb +24 -0
- data/lib/rosetta_queue/consumer_managers/evented.rb +43 -0
- data/lib/rosetta_queue/consumer_managers/threaded.rb +94 -0
- data/lib/rosetta_queue/core_ext/string.rb +22 -0
- data/lib/rosetta_queue/core_ext/time.rb +20 -0
- data/lib/rosetta_queue/destinations.rb +33 -0
- data/lib/rosetta_queue/exception_handler.rb +105 -0
- data/lib/rosetta_queue/exceptions.rb +10 -0
- data/lib/rosetta_queue/filters.rb +58 -0
- data/lib/rosetta_queue/logger.rb +27 -0
- data/lib/rosetta_queue/message_handler.rb +52 -0
- data/lib/rosetta_queue/producer.rb +21 -0
- data/lib/rosetta_queue/spec_helpers.rb +5 -0
- data/lib/rosetta_queue/spec_helpers/hash.rb +21 -0
- data/lib/rosetta_queue/spec_helpers/helpers.rb +47 -0
- data/lib/rosetta_queue/spec_helpers/publishing_matchers.rb +144 -0
- data/spec/rosetta_queue/adapter_spec.rb +101 -0
- data/spec/rosetta_queue/adapters/amqp_synchronous_spec.rb +277 -0
- data/spec/rosetta_queue/adapters/beanstalk_spec.rb +47 -0
- data/spec/rosetta_queue/adapters/fake_spec.rb +72 -0
- data/spec/rosetta_queue/adapters/null_spec.rb +31 -0
- data/spec/rosetta_queue/adapters/shared_adapter_behavior.rb +38 -0
- data/spec/rosetta_queue/adapters/shared_fanout_behavior.rb +20 -0
- data/spec/rosetta_queue/adapters/stomp_spec.rb +126 -0
- data/spec/rosetta_queue/consumer_managers/evented_spec.rb +56 -0
- data/spec/rosetta_queue/consumer_managers/shared_manager_behavior.rb +26 -0
- data/spec/rosetta_queue/consumer_managers/threaded_spec.rb +51 -0
- data/spec/rosetta_queue/consumer_spec.rb +99 -0
- data/spec/rosetta_queue/core_ext/string_spec.rb +15 -0
- data/spec/rosetta_queue/destinations_spec.rb +34 -0
- data/spec/rosetta_queue/exception_handler_spec.rb +106 -0
- data/spec/rosetta_queue/filters_spec.rb +57 -0
- data/spec/rosetta_queue/message_handler_spec.rb +47 -0
- data/spec/rosetta_queue/producer_spec.rb +77 -0
- data/spec/rosetta_queue/shared_messaging_behavior.rb +21 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +47 -0
- metadata +142 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
Given /^a consumer is listening to queue '(.*)'$/ do |queue|
|
2
|
+
klass = eval_consumer_class(queue)
|
3
|
+
@thread = Thread.new do
|
4
|
+
cons = klass.new
|
5
|
+
case @adapter_type
|
6
|
+
when /evented/
|
7
|
+
EM.run do
|
8
|
+
RosettaQueue::Consumer.new(cons).receive
|
9
|
+
end
|
10
|
+
else
|
11
|
+
RosettaQueue::Consumer.new(cons).receive
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Then /^the message should be consumed from '(.*)'$/ do |queue|
|
17
|
+
sleep 1
|
18
|
+
file_path = "#{CONSUMER_LOG_DIR}/point-to-point.log"
|
19
|
+
# sleep 1 unless File.exists?(file_path)
|
20
|
+
File.readlines(file_path).last.should =~ /Hello World! from #{queue.capitalize}Consumer/
|
21
|
+
@thread.kill
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Given /^multiple consumers are listening to queue '(.*)'$/ do |queue|
|
2
|
+
@managers = []
|
3
|
+
Thread.new do
|
4
|
+
@managers << RosettaQueue::ThreadedManager.create do |m|
|
5
|
+
m.add(eval_consumer_class(queue, "fooconsumer.log", "FooConsumer").new)
|
6
|
+
m.start
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Thread.new do
|
11
|
+
@managers << RosettaQueue::ThreadedManager.create do |m|
|
12
|
+
m.add(eval_consumer_class(queue, "barconsumer.log", "BarConsumer").new)
|
13
|
+
m.start
|
14
|
+
end
|
15
|
+
end
|
16
|
+
sleep 5
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /^multiple messages should be consumed from '(\w+)'$/ do |queue|
|
20
|
+
["FooConsumer", "BarConsumer"].each do |class_name, value|
|
21
|
+
file_path = "#{CONSUMER_LOG_DIR}/#{class_name.downcase}.log"
|
22
|
+
File.readlines(file_path).last.should =~ /Hello World! from #{class_name}/
|
23
|
+
end
|
24
|
+
@managers.each {|m| m.stop_threads }
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
$:.unshift(File.dirname(__FILE__) + '/../../lib')
|
3
|
+
require 'rosetta_queue'
|
4
|
+
require 'rosetta_queue/spec_helpers'
|
5
|
+
require 'spec/expectations'
|
6
|
+
require 'rosetta_queue/spec_helpers'
|
7
|
+
|
8
|
+
CONSUMER_LOG_DIR = File.expand_path(File.dirname(__FILE__) + "/../support/tmp")
|
9
|
+
|
10
|
+
begin
|
11
|
+
RosettaQueue.logger = RosettaQueue::Logger.new(File.join(File.dirname(__FILE__), '../../../log', 'rosetta_queue.log'))
|
12
|
+
rescue Errno::ENOENT
|
13
|
+
Kernel.warn "No log directory setup at the root of rosetta_queue. Using the null logger instead."
|
14
|
+
class NullLogger
|
15
|
+
def info(*args); end
|
16
|
+
def debug(*args); end
|
17
|
+
def fatal(*args); end
|
18
|
+
def error(*args); end
|
19
|
+
def warn(*args); end
|
20
|
+
end
|
21
|
+
|
22
|
+
RosettaQueue.logger = NullLogger.new
|
23
|
+
end
|
24
|
+
|
25
|
+
World(RosettaQueue::SpecHelpers)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/env.rb')
|
2
|
+
|
3
|
+
class SampleConsumer
|
4
|
+
include ::RosettaQueue::MessageHandler
|
5
|
+
subscribes_to :foo
|
6
|
+
options :durable => true
|
7
|
+
|
8
|
+
attr_reader :msg
|
9
|
+
|
10
|
+
def on_message(msg)
|
11
|
+
@msg = msg
|
12
|
+
puts "MESSAGE #{msg}"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
class SampleConsumerTwo
|
19
|
+
include ::RosettaQueue::MessageHandler
|
20
|
+
subscribes_to :foo
|
21
|
+
options :durable => true
|
22
|
+
|
23
|
+
attr_reader :msg
|
24
|
+
|
25
|
+
def on_message(msg)
|
26
|
+
@msg = msg
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require('rosetta_queue/core_ext/string') unless defined? ActiveSupport
|
4
|
+
require('rosetta_queue/core_ext/time') unless defined? ActiveSupport
|
5
|
+
|
6
|
+
require 'rosetta_queue/adapter'
|
7
|
+
require 'rosetta_queue/base'
|
8
|
+
require 'rosetta_queue/consumer'
|
9
|
+
require 'rosetta_queue/destinations'
|
10
|
+
require 'rosetta_queue/exceptions'
|
11
|
+
require 'rosetta_queue/filters'
|
12
|
+
require 'rosetta_queue/logger'
|
13
|
+
require 'rosetta_queue/message_handler'
|
14
|
+
require 'rosetta_queue/exception_handler'
|
15
|
+
require 'rosetta_queue/producer'
|
16
|
+
require 'rosetta_queue/consumer_managers/base'
|
17
|
+
require 'rosetta_queue/consumer_managers/threaded'
|
18
|
+
|
19
|
+
if defined?(Rails)
|
20
|
+
RosettaQueue.logger = RosettaQueue::Logger.new(File.join(Rails.root, 'log', 'rosetta_queue.log'))
|
21
|
+
require('rosetta_queue/spec_helpers') if Rails.env == "test"
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rosetta_queue/adapters/base'
|
2
|
+
|
3
|
+
module RosettaQueue
|
4
|
+
class Adapter
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_writer :user, :password, :host, :port, :options
|
8
|
+
|
9
|
+
def define
|
10
|
+
yield self
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset
|
14
|
+
@user, @password, @host, @port, @options, @adapter_class = nil, nil, nil, nil, nil, nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def type=(adapter_prefix)
|
18
|
+
require "rosetta_queue/adapters/#{adapter_prefix}"
|
19
|
+
@adapter_class = RosettaQueue::Gateway.const_get("#{adapter_prefix.to_s.classify}Adapter")
|
20
|
+
|
21
|
+
rescue LoadError
|
22
|
+
raise AdapterException, "Adapter type '#{adapter_prefix}' does not match existing adapters!"
|
23
|
+
end
|
24
|
+
|
25
|
+
def instance
|
26
|
+
raise AdapterException, "Adapter type was never defined!" unless @adapter_class
|
27
|
+
@adapter_class.new({:user => @user, :password => @password, :host => @host, :port => @port, :opts => opts})
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def opts
|
33
|
+
raise AdapterException, "Adapter options should be a hash" unless @options.nil? || @options.is_a?(Hash)
|
34
|
+
@options ||= {}
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RosettaQueue
|
2
|
+
module Gateway
|
3
|
+
|
4
|
+
module Fanout
|
5
|
+
def fanout_name_for(destination)
|
6
|
+
fanout_name = destination.gsub(/(topic|fanout)\/(.*)/, '\2')
|
7
|
+
raise AdapterException, "Unable to discover fanout exchange. Cannot bind queue to exchange!" unless fanout_name
|
8
|
+
fanout_name
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Amqp < BaseAdapter
|
13
|
+
|
14
|
+
def initialize(adapter_settings = {})
|
15
|
+
raise AdapterException, "Missing adapter settings" if adapter_settings.empty?
|
16
|
+
@adapter_settings = adapter_settings
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete(destination, opts={})
|
20
|
+
exchange_strategy_for(destination, opts).delete(destination)
|
21
|
+
end
|
22
|
+
|
23
|
+
def disconnect(message_handler)
|
24
|
+
destination = destination_for(message_handler)
|
25
|
+
exchange_strategy_for(destination).unsubscribe
|
26
|
+
end
|
27
|
+
|
28
|
+
def receive_once(destination, opts={})
|
29
|
+
exchange_strategy_for(destination, opts).receive_once(destination) do |msg|
|
30
|
+
return msg
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def receive_with(message_handler)
|
35
|
+
options = options_for(message_handler)
|
36
|
+
destination = destination_for(message_handler)
|
37
|
+
exchange_strategy_for(destination, options).receive(destination, message_handler)
|
38
|
+
end
|
39
|
+
|
40
|
+
def send_message(destination, message, options=nil)
|
41
|
+
exchange_strategy_for(destination, options).publish(destination, message)
|
42
|
+
end
|
43
|
+
|
44
|
+
def unsubscribe; end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'mq'
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + "/amqp.rb")
|
4
|
+
|
5
|
+
module RosettaQueue
|
6
|
+
module Gateway
|
7
|
+
|
8
|
+
class AmqpEventedAdapter < Amqp
|
9
|
+
private
|
10
|
+
|
11
|
+
def exchange_strategy_for(destination, options)
|
12
|
+
case destination
|
13
|
+
when /^fanout\./
|
14
|
+
@exchange ||= EventedExchange::FanoutExchange.new(@adapter_settings, options)
|
15
|
+
when /^topic\./
|
16
|
+
raise "Sorry. RosettaQueue can not process AMQP topics yet"
|
17
|
+
when /^queue\./
|
18
|
+
@exchange ||= EventedExchange::DirectExchange.new(@adapter_settings, options)
|
19
|
+
else
|
20
|
+
@exchange ||= EventedExchange::DirectExchange.new(@adapter_settings, options)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module EventedExchange
|
26
|
+
|
27
|
+
class BaseExchange
|
28
|
+
|
29
|
+
def initialize(adapter_settings, options={})
|
30
|
+
@adapter_settings, @options = adapter_settings, options
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(destination)
|
34
|
+
conn.queue(destination).delete(@options)
|
35
|
+
end
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def channel
|
40
|
+
@channel ||= MQ.new(conn)
|
41
|
+
end
|
42
|
+
|
43
|
+
def conn
|
44
|
+
vhost = @adapter_settings[:opts][:vhost] || "/"
|
45
|
+
@conn ||= AMQP.connect(:user => @adapter_settings[:user],
|
46
|
+
:pass => @adapter_settings[:password],
|
47
|
+
:host => @adapter_settings[:host],
|
48
|
+
:vhost => vhost)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
class DirectExchange < BaseExchange
|
54
|
+
|
55
|
+
def publish(destination, message, options={})
|
56
|
+
raise AdapterException, "Messages need to be published in an EventMachine run block (e.g., EM.run { RosettaQueue::Producer.publish(:foo, msg) } " unless EM.reactor_running?
|
57
|
+
|
58
|
+
queue = channel.queue(destination, options)
|
59
|
+
queue.publish(message, options)
|
60
|
+
RosettaQueue.logger.info("Publishing to #{destination} :: #{message}")
|
61
|
+
queue.unsubscribe
|
62
|
+
end
|
63
|
+
|
64
|
+
def receive(destination, message_handler)
|
65
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. Try wrapping them inside the evented consumer manager." unless EM.reactor_running?
|
66
|
+
|
67
|
+
queue = channel.queue(destination, @options)
|
68
|
+
ack = @options[:ack]
|
69
|
+
queue.subscribe(@options) do |header, msg|
|
70
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
71
|
+
message_handler.handle_message(msg)
|
72
|
+
header.ack if ack
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def receive_once(destination, options={})
|
77
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. (e.g., EM.run { RosettaQueue::Consumer.receive }" unless EM.reactor_running?
|
78
|
+
|
79
|
+
queue = channel.queue(destination, @options)
|
80
|
+
ack = @options[:ack]
|
81
|
+
queue.pop(@options) do |header, msg|
|
82
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
83
|
+
header.ack if ack
|
84
|
+
yield Filters.process_receiving(msg)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
class FanoutExchange < BaseExchange
|
91
|
+
include Fanout
|
92
|
+
|
93
|
+
def publish(dest, msg, opts)
|
94
|
+
raise AdapterException, "Messages need to be published in an EventMachine run block (e.g., EM.run { RosettaQueue::Producer.publish(:foo, msg) } " unless EM.reactor_running?
|
95
|
+
|
96
|
+
exchange = channel.fanout(fanout_name_for(dest), opts)
|
97
|
+
exchange.publish(msg, opts)
|
98
|
+
RosettaQueue.logger.info("Publishing to fanout #{dest} :: #{msg}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def receive(destination, message_handler)
|
102
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. Try wrapping them inside the evented consumer manager." unless EM.reactor_running?
|
103
|
+
|
104
|
+
queue = channel.queue("queue_#{self.object_id}")
|
105
|
+
exchange = channel.fanout(fanout_name_for(destination), @options)
|
106
|
+
ack = @options[:ack]
|
107
|
+
|
108
|
+
queue.bind(exchange).subscribe(@options) do |header, msg|
|
109
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
110
|
+
message_handler.handle_message(msg)
|
111
|
+
header.ack if ack
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def receive_once(destination, opts={})
|
116
|
+
raise AdapterException, "Consumers need to run in an EventMachine 'run' block. (e.g., EM.run { RosettaQueue::Consumer.receive }" unless EM.reactor_running?
|
117
|
+
|
118
|
+
queue = channel.queue("queue_#{self.object_id}")
|
119
|
+
exchange = channel.fanout(fanout_name_for(destination), opts)
|
120
|
+
ack = @options[:ack]
|
121
|
+
|
122
|
+
queue.bind(exchange).pop(opts) do |header, msg|
|
123
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
124
|
+
header.ack if ack
|
125
|
+
yield Filters.process_receiving(msg)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'bunny'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/amqp.rb")
|
3
|
+
|
4
|
+
module RosettaQueue
|
5
|
+
module Gateway
|
6
|
+
|
7
|
+
# This AMQP adapter utilizes the synchronous AMPQ client 'Bunny'
|
8
|
+
# by celldee (http://github.com/celldee/bunny)
|
9
|
+
class AmqpSynchAdapter < Amqp
|
10
|
+
private
|
11
|
+
|
12
|
+
def exchange_strategy_for(destination, options={})
|
13
|
+
case destination
|
14
|
+
when /^fanout\./
|
15
|
+
@exchange ||= SynchExchange::FanoutExchange.new(@adapter_settings, options)
|
16
|
+
when /^topic\./
|
17
|
+
raise "Sorry. RosettaQueue can not process AMQP topics yet"
|
18
|
+
when /^queue\./
|
19
|
+
@exchange ||= SynchExchange::DirectExchange.new(@adapter_settings, options)
|
20
|
+
else
|
21
|
+
@exchange ||= SynchExchange::DirectExchange.new(@adapter_settings, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module SynchExchange
|
27
|
+
|
28
|
+
class BaseExchange
|
29
|
+
|
30
|
+
def initialize(adapter_settings, options={})
|
31
|
+
@adapter_settings, @options = adapter_settings, options
|
32
|
+
end
|
33
|
+
|
34
|
+
def delete(destination, options={})
|
35
|
+
conn.queue(destination).delete(options)
|
36
|
+
end
|
37
|
+
|
38
|
+
def unsubscribe
|
39
|
+
@queue.unsubscribe
|
40
|
+
conn.stop
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
def conn
|
46
|
+
vhost = @adapter_settings[:opts][:vhost] || "/"
|
47
|
+
@conn ||= Bunny.new( :user => @adapter_settings[:user],
|
48
|
+
:pass => @adapter_settings[:password],
|
49
|
+
:host => @adapter_settings[:host],
|
50
|
+
:vhost => vhost)
|
51
|
+
@conn.start unless @conn.status == :connected
|
52
|
+
@conn
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
class DirectExchange < BaseExchange
|
58
|
+
|
59
|
+
def publish(destination, message, options={})
|
60
|
+
RosettaQueue.logger.info("Publishing to #{destination} :: #{message}")
|
61
|
+
queue = conn.queue(destination, options)
|
62
|
+
queue.publish(message, options)
|
63
|
+
conn.stop
|
64
|
+
end
|
65
|
+
|
66
|
+
def receive(destination, message_handler)
|
67
|
+
ack = @options[:ack]
|
68
|
+
@queue = conn.queue(destination, @options)
|
69
|
+
@queue.subscribe(@options) do |msg|
|
70
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
71
|
+
message_handler.handle_message(msg)
|
72
|
+
@queue.ack if ack
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def receive_once(destination, options = {})
|
77
|
+
ack = options[:ack]
|
78
|
+
@queue = conn.queue(destination, options)
|
79
|
+
msg = @queue.pop(options)
|
80
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
81
|
+
@queue.ack if ack
|
82
|
+
yield Filters.process_receiving(msg)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
class FanoutExchange < BaseExchange
|
88
|
+
include Fanout
|
89
|
+
|
90
|
+
def publish(destination, message, options={})
|
91
|
+
exchange = conn.exchange(fanout_name_for(destination), options.merge({:type => :fanout}))
|
92
|
+
exchange.publish(message, options)
|
93
|
+
RosettaQueue.logger.info("Publishing to fanout #{destination} :: #{message}")
|
94
|
+
end
|
95
|
+
|
96
|
+
def receive(destination, message_handler)
|
97
|
+
ack = @options[:ack]
|
98
|
+
@queue = conn.queue("queue_#{self.object_id}", @options)
|
99
|
+
exchange = conn.exchange(fanout_name_for(destination), @options.merge({:type => :fanout}))
|
100
|
+
@queue.bind(exchange)
|
101
|
+
@queue.subscribe(@options) do |msg|
|
102
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
103
|
+
message_handler.handle_message(msg)
|
104
|
+
@queue.ack if ack
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def receive_once(destination, options={})
|
109
|
+
ack = options[:ack]
|
110
|
+
@queue = conn.queue("queue_#{self.object_id}", options)
|
111
|
+
exchange = conn.exchange(fanout_name_for(destination), options.merge({:type => :fanout}))
|
112
|
+
@queue.bind(exchange)
|
113
|
+
msg = @queue.pop(options)
|
114
|
+
RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
|
115
|
+
@queue.ack if ack
|
116
|
+
yield Filters.process_receiving(msg)
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|