cwyckoff-rosetta_queue 0.2.2 → 0.3.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/README.rdoc CHANGED
@@ -4,17 +4,21 @@ Rosetta Queue is a messaging gateway API with adapters for many messaging system
4
4
 
5
5
  The adapters provided currently are for stomp, amqp, and beanstalk. We would like to add adapters for other messaging gateways. The stomp adapter has been used in production along side with Apache's ActiveMQ. The amqp adapter currently works along side RabbitMQ and passes the acceptance tests but as of yet has not been used in production.
6
6
 
7
+
7
8
  == Quick Tutorial
9
+
8
10
  Note: The API will most likely change until we reach 1.0. We will be moving to a more concise API (i.e. queue(:test_queue) << message, etc...) We will also be changing how exceptions are handled.
9
11
 
10
12
  When using Rosetta Queue in an application you will need to configure the queues, adapters, and filters (optional). These configurations should be placed in a file that gets loaded once when your program starts. If you are using Rails then a good place for this is config/initializers/rosetta_queue.rb.
11
13
 
12
- To set up destinations to produce messages to and consume messages from:
14
+
15
+ To set up destinations for producing and consuming messages:
13
16
 
14
17
  RosettaQueue::Destinations.define do |queue|
15
18
  queue.map :test_queue, '/queue/my_test_queue'
16
19
  end
17
20
 
21
+
18
22
  Defining your adapter:
19
23
 
20
24
  RosettaQueue::Adapter.define do |a|
@@ -25,6 +29,7 @@ Defining your adapter:
25
29
  a.type = "stomp"
26
30
  end
27
31
 
32
+
28
33
  Define a logger for Rosetta Queue to use. The logger should be a standard ruby logger:
29
34
 
30
35
  RosettaQueue.logger = Logger.new('/my_project/rosetta_queue.log')
@@ -76,11 +81,31 @@ It is recommended that you set your adapter to the 'null' adapter for your specs
76
81
  Please look at the publishing matchers for more information. For examples on how to write acceptance tests for your Rosetta Queue's code please see RosettaQueue's own Cucumber features and read this {blog post}[http://www.benmabey.com/2009/02/17/using-cucumber-to-integrate-distributed-systems-and-test-messaging/].
77
82
 
78
83
 
84
+ === AMQP
85
+
86
+ The AMQP adapter is based on the synchronous AMQP ruby client "Bunny" by celldee [http://github.com/celldee/bunny]. The original AMQP adapter for RosettaQueue was the 'evented' client by Aman Gupta [http://github.com/tmm1/amqp], but the evented model posed some problems for our integration tests. That, and the desire to keep things simple led us to use a synchronous AMQP client.
87
+
88
+ ==== Configuration
89
+
90
+ If you are using the AMQP adapter, there are some important rules when defining the adapter and mapping your destinations. Two of the basic building blocks of AMQP are queues and exchanges. Queues bind to exchanges in several different ways. A can queue bind to an exchange and requests messages that match a specific routing key, which is called 'direct exchange' and is analogous to the 'point-to-point' messaging pattern. Alternately, queues can bind to an exchange to receive all messages sent to that exchange; this is called 'fanout exchange' and is analogous to the 'publish-subscribe' pattern. So, when you want to define a simple 'direct-exchange' queue, your queue name must begin with the term "queue".
91
+
92
+ RosettaQueue::Destinations.define do |queue|
93
+ queue.map :test_queue, 'queue.my_test_queue'
94
+ end
95
+
96
+ And, when you want to define a queue that will bind to a 'fanout-exchange', your queue name must begin with the term "fanout".
97
+
98
+ RosettaQueue::Destinations.define do |queue|
99
+ queue.map :test_queue, 'fanout.my_test_queue'
100
+ end
101
+
102
+ Oh, and when defining your adapter, be sure to specify the AMQP adapter as :amqp_synch, not :amqp. This way, if we do get around to adding Aman's evented AMQP client, we can distinguish between the synchronous and asynchronous clients (i.e., :amqp_sync vs. :amqp_asynch).
103
+
79
104
 
80
105
  == How to contribute
81
106
  ----------------------------------------------------------------
82
107
  Gems you will need:
83
- cucumber, rspec, yaml, stomp, tmm1-amqp, beanstalk-client
108
+ cucumber, rspec, yaml, stomp, bunny, beanstalk-client
84
109
 
85
110
  You should be able to run the rspec code examples (specs) without any brokers running with autospec or 'rake spec'.
86
111
 
data/Rakefile CHANGED
@@ -18,8 +18,8 @@ begin
18
18
  s.name = "rosetta_queue"
19
19
  s.rubyforge_project = "rosetta-queue"
20
20
  s.summary = %Q{Messaging gateway API with adapters for many messaging systems available in Ruby.}
21
- s.email = "ben@benmabey.com"
22
- s.homepage = "http://github.com/bmabey/rosetta_queue"
21
+ s.email = "cbwyckoff@gmail.com"
22
+ s.homepage = "http://github.com/cwyckoff/rosetta_queue"
23
23
  s.description = %Q{Messaging gateway API with adapters for many messaging systems available in Ruby. Messaging systems can be easily switched out with a small configuration change. Code for testing on the object and application level is also provided.}
24
24
  s.extra_rdoc_files = ["README.rdoc", "MIT-LICENSE.txt"]
25
25
  s.files = FileList["[A-Z]*.*", "{bin,generators,lib,features,spec}/**/*", "Rakefile", "cucumber.yml"]
data/lib/rosetta_queue.rb CHANGED
@@ -11,6 +11,8 @@ require 'rosetta_queue/filters'
11
11
  require 'rosetta_queue/logger'
12
12
  require 'rosetta_queue/message_handler'
13
13
  require 'rosetta_queue/producer'
14
+ require 'rosetta_queue/consumer_managers/base'
15
+ require 'rosetta_queue/consumer_managers/threaded'
14
16
 
15
17
  if defined?(Rails)
16
18
  RosettaQueue.logger = RosettaQueue::Logger.new(File.join(Rails.root, 'log', 'rosetta_queue.log'))
@@ -1,11 +1,11 @@
1
- require 'carrot'
1
+ require 'bunny'
2
2
 
3
3
  module RosettaQueue
4
4
  module Gateway
5
5
 
6
- # This AMQP adapter utilizes a forked version of the synchronous AMPQ client 'Carrot'
7
- # by famoseagle (http://github.com/famoseagle)
8
- class AmqpAdapter < BaseAdapter
6
+ # This AMQP adapter utilizes the synchronous AMPQ client 'Bunny'
7
+ # by celldee (http://github.com/celldee/bunny)
8
+ class AmqpSynchAdapter < BaseAdapter
9
9
 
10
10
  def initialize(adapter_settings = {})
11
11
  raise AdapterException, "Missing adapter settings" if adapter_settings.empty?
@@ -40,11 +40,11 @@ module RosettaQueue
40
40
 
41
41
  def exchange_strategy_for(destination, options)
42
42
  case destination
43
- when /fanout/
43
+ when /^fanout\./
44
44
  @exchange ||= AmqpExchangeStrategies::FanoutExchange.new(@adapter_settings, options)
45
- when /topic/
45
+ when /^topic\./
46
46
  raise "Sorry. RosettaQueue can not process AMQP topics yet"
47
- when /queue/
47
+ when /^queue\./
48
48
  @exchange ||= AmqpExchangeStrategies::DirectExchange.new(@adapter_settings, options)
49
49
  else
50
50
  @exchange ||= AmqpExchangeStrategies::DirectExchange.new(@adapter_settings, options)
@@ -66,12 +66,15 @@ module RosettaQueue
66
66
  end
67
67
 
68
68
  protected
69
+
69
70
  def conn
70
71
  vhost = @adapter_settings[:opts][:vhost] || "/"
71
- @conn ||= Carrot.new(:user => @adapter_settings[:user],
72
+ @conn ||= Bunny.new( :user => @adapter_settings[:user],
72
73
  :pass => @adapter_settings[:password],
73
74
  :host => @adapter_settings[:host],
74
75
  :vhost => vhost)
76
+ @conn.start unless @conn.status == :connected
77
+ @conn
75
78
  end
76
79
  end
77
80
 
@@ -83,15 +86,21 @@ module RosettaQueue
83
86
  end
84
87
 
85
88
  def receive(destination, message_handler)
86
- conn.queue(destination, @options).subscribe(@options) do |msg|
89
+ queue = conn.queue(destination, @options)
90
+ ack = @options[:ack]
91
+ queue.subscribe(@options) do |msg|
87
92
  RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
88
93
  message_handler.on_message(Filters.process_receiving(msg))
94
+ queue.ack if ack
89
95
  end
90
96
  end
91
97
 
92
98
  def receive_once(destination, options={})
93
- msg = conn.queue(destination, options).pop(options)
99
+ q = conn.queue(destination, @options)
100
+ ack = @options[:ack]
101
+ msg = q.pop(options)
94
102
  RosettaQueue.logger.info("Receiving from #{destination} :: #{msg}")
103
+ q.ack if ack
95
104
  yield Filters.process_receiving(msg)
96
105
  end
97
106
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cwyckoff-rosetta_queue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Mabey
@@ -31,7 +31,7 @@ files:
31
31
  - lib/rosetta_queue
32
32
  - lib/rosetta_queue/adapter.rb
33
33
  - lib/rosetta_queue/adapters
34
- - lib/rosetta_queue/adapters/amqp.rb
34
+ - lib/rosetta_queue/adapters/amqp_synch.rb
35
35
  - lib/rosetta_queue/adapters/base.rb
36
36
  - lib/rosetta_queue/adapters/fake.rb
37
37
  - lib/rosetta_queue/adapters/null.rb