action_subscriber 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -0
  3. data/.travis.yml +12 -0
  4. data/Gemfile +0 -1
  5. data/README.md +10 -4
  6. data/action_subscriber.gemspec +2 -2
  7. data/lib/action_subscriber/base.rb +13 -0
  8. data/lib/action_subscriber/dsl.rb +16 -6
  9. data/lib/action_subscriber/middleware/error_handler.rb +0 -1
  10. data/lib/action_subscriber/middleware/router.rb +1 -5
  11. data/lib/action_subscriber/rabbit_connection.rb +10 -0
  12. data/lib/action_subscriber/version.rb +1 -1
  13. data/spec/integration/around_filters_spec.rb +38 -0
  14. data/spec/integration/at_least_once_spec.rb +23 -0
  15. data/spec/integration/at_most_once_spec.rb +23 -0
  16. data/spec/integration/automatic_reconnect_spec.rb +43 -0
  17. data/spec/integration/basic_subscriber_spec.rb +25 -19
  18. data/spec/integration/decoding_payloads_spec.rb +48 -0
  19. data/spec/integration/manual_acknowledgement_spec.rb +27 -0
  20. data/spec/lib/action_subscriber/base_spec.rb +0 -2
  21. data/spec/lib/action_subscriber/configuration_spec.rb +0 -2
  22. data/spec/lib/action_subscriber/dsl_spec.rb +0 -42
  23. data/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb +0 -1
  24. data/spec/lib/action_subscriber/middleware/active_record/query_cache_spec.rb +0 -1
  25. data/spec/lib/action_subscriber/middleware/decoder_spec.rb +0 -2
  26. data/spec/lib/action_subscriber/middleware/env_spec.rb +0 -2
  27. data/spec/lib/action_subscriber/middleware/error_handler_spec.rb +0 -13
  28. data/spec/lib/action_subscriber/middleware/router_spec.rb +0 -14
  29. data/spec/lib/action_subscriber/middleware/runner_spec.rb +0 -2
  30. data/spec/lib/action_subscriber/subscribable_spec.rb +0 -2
  31. data/spec/lib/action_subscriber/threadpool_spec.rb +0 -2
  32. data/spec/spec_helper.rb +12 -6
  33. metadata +26 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14ee094f6885fec532698cf8eac89dca3f79978e
4
- data.tar.gz: 54740c601d44855e1260483ebfd73e7e042eee93
3
+ metadata.gz: 6a9be445a43340a38817ee6efe76c6c3063dcca4
4
+ data.tar.gz: 4f33caa19d68cfcf1e8b2b6732e3e82e5396ea5e
5
5
  SHA512:
6
- metadata.gz: bdd0d984f012f90c8100fa5c079dd7dee1c02362f7a5e93c4c2686758057ca4be52e53d17c820c7ddb1f39b68782048955d071811068183f7ff71a516bcf1211
7
- data.tar.gz: 1c5543030e5b226fb9f97655454f3f644778c375a9b44a8c08742ec7795c1514d4b99adeb9498275e98c5b7891e3427cab4062a600bef1d9cd52e5f7f4de58c3
6
+ metadata.gz: 1a7b01e0746d3266a66fb1487b6ea495ea9cfa13553df1d91cb7b27173bff2e61627c893bdd9cbe44ff5391d1623f73cb781afb2675e060a2d8b728b9713cdda
7
+ data.tar.gz: e7df2fa7ffa73affb739a4fa9f7f5b2d0abd093fd58638c610b3bc783a1f9a1ad5ef7d14473c9777e84424a575a029d2440788e7b715c05a2f9c4f71385bb766
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --colour
2
2
  --order rand
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
7
+ - jruby
8
+ - jruby-head
9
+ services:
10
+ - rabbitmq
11
+ sudo: false
12
+ cache: bundler
data/Gemfile CHANGED
@@ -1,5 +1,4 @@
1
1
  source 'https://rubygems.org'
2
- source 'http://gems.moneydesktop.com'
3
2
 
4
3
  # Specify your gem's dependencies in action_subscriber.gemspec
5
4
  gemspec
data/README.md CHANGED
@@ -1,3 +1,7 @@
1
+ [![Build Status](https://travis-ci.org/moneydesktop/action_subscriber.svg?branch=master)](https://travis-ci.org/moneydesktop/action_subscriber)
2
+ [![Code Climate](https://codeclimate.com/github/moneydesktop/action_subscriber/badges/gpa.svg)](https://codeclimate.com/github/moneydesktop/action_subscriber)
3
+ [![Dependency Status](https://gemnasium.com/moneydesktop/action_subscriber.svg)](https://gemnasium.com/moneydesktop/action_subscriber)
4
+
1
5
  ActionSubscriber
2
6
  =================
3
7
  ActionSubscriber is a DSL for for easily intergrating your Rails app with a RabbitMQ messaging server.
@@ -66,19 +70,21 @@ ActionSubscriber needs to know how to connect to your rabbit server to start get
66
70
  In an initializer, you can set the host and the port like this :
67
71
 
68
72
  ActionSubscriber::Configuration.configure do |config|
69
- config.host = "my rabbit host"
73
+ config.hosts = ["rabbit1", "rabbit2", "rabbit3"]
70
74
  config.port = 5672
71
75
  end
72
76
 
73
77
  Other configuration options include :
74
78
 
79
+ * config.add_decoder - add a custom decoder for a custom content type
75
80
  * config.allow_low_priority_methods - subscribe to queues for methods suffixed with "_low"
76
81
  * config.default_exchange - set the default exchange that your queues will use, using the default RabbitMQ exchange is not recommended
82
+ * config.error_handler - handle error like you want to handle them!
83
+ * config.heartbeat - number of seconds between hearbeats (default 5) [see bunny documentation for more details](http://rubybunny.info/articles/connecting.html)
77
84
  * config.hosts - an array of hostnames in your cluster
78
- * config.times_to_pop - when using RabbitMQ's pull API, the number of messages we will grab each time we pool the broker
79
85
  * config.threadpool_size - set the number of threads availiable to action_subscriber
80
- * config.error_handler - handle error like you want to handle them!
81
- * config.add_decoder - add a custom decoder for a custom content type
86
+ * config.timeout - how many seconds to allow rabbit to respond before timing out
87
+ * config.times_to_pop - when using RabbitMQ's pull API, the number of messages we will grab each time we pool the broker
82
88
 
83
89
  Message Acknowledgment
84
90
  ----------------------
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["brianastien@gmail.com","liveh2o@gmail.com","brandonsdewitt@gmail.com","quixoten@gmail.com","michael@riesd.com"]
11
11
  spec.description = %q{ActionSubscriber is a DSL that allows a rails app to consume messages from a RabbitMQ broker.}
12
12
  spec.summary = %q{ActionSubscriber is a DSL that allows a rails app to consume messages from a RabbitMQ broker.}
13
- spec.homepage = ""
13
+ spec.homepage = "https://github.com/moneydesktop/action_subscriber"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.add_development_dependency "activerecord", ">= 3.2"
33
33
  spec.add_development_dependency "bundler", ">= 1.6"
34
34
  spec.add_development_dependency "pry-nav"
35
+ spec.add_development_dependency "rabbitmq_http_api_client", "~> 1.2.0"
35
36
  spec.add_development_dependency "rspec", "~> 3.0"
36
37
  spec.add_development_dependency "rake"
37
- spec.add_development_dependency "simplecov"
38
38
  end
@@ -76,6 +76,19 @@ module ActionSubscriber
76
76
  env.acknowledge
77
77
  end
78
78
 
79
+ def _at_least_once_filter
80
+ yield
81
+ acknowledge
82
+ rescue => error
83
+ reject
84
+ raise error
85
+ end
86
+
87
+ def _at_most_once_filter
88
+ acknowledge
89
+ yield
90
+ end
91
+
79
92
  def reject
80
93
  env.reject
81
94
  end
@@ -2,24 +2,24 @@ module ActionSubscriber
2
2
  module DSL
3
3
  def at_least_once!
4
4
  @_acknowledge_messages = true
5
- @_acknowledge_messages_after_processing = true
5
+ around_filter :_at_least_once_filter
6
6
  end
7
7
 
8
8
  def at_most_once!
9
9
  @_acknowledge_messages = true
10
- @_acknowledge_messages_before_processing = true
10
+ around_filter :_at_most_once_filter
11
11
  end
12
12
 
13
13
  def acknowledge_messages?
14
14
  !!@_acknowledge_messages
15
15
  end
16
16
 
17
- def acknowledge_messages_after_processing?
18
- !!@_acknowledge_messages_after_processing
17
+ def around_filter(filter_method)
18
+ around_filters << filter_method
19
19
  end
20
20
 
21
- def acknowledge_messages_before_processing?
22
- !!@_acknowledge_messages_before_processing
21
+ def around_filters
22
+ @_around_filters ||= []
23
23
  end
24
24
 
25
25
  # Explicitly set the name of the exchange
@@ -79,5 +79,15 @@ module ActionSubscriber
79
79
  def routing_key_names
80
80
  @_routing_key_names ||= {}
81
81
  end
82
+
83
+ def run_action_with_filters(env, action)
84
+ subscriber_instance = self.new(env)
85
+ final_block = Proc.new { subscriber_instance.public_send(action) }
86
+
87
+ first_proc = around_filters.reverse.reduce(final_block) do |block, filter|
88
+ Proc.new { subscriber_instance.send(filter, &block) }
89
+ end
90
+ first_proc.call
91
+ end
82
92
  end
83
93
  end
@@ -8,7 +8,6 @@ module ActionSubscriber
8
8
  def call(env)
9
9
  @app.call(env)
10
10
  rescue => error
11
- env.reject if env.subscriber.acknowledge_messages_after_processing?
12
11
  ::ActionSubscriber.configuration.error_handler.call(error, env.to_h)
13
12
  end
14
13
  end
@@ -6,11 +6,7 @@ module ActionSubscriber
6
6
  end
7
7
 
8
8
  def call(env)
9
- subscriber = env.subscriber.new(env)
10
-
11
- env.acknowledge if env.subscriber.acknowledge_messages_before_processing?
12
- subscriber.public_send(env.action)
13
- env.acknowledge if env.subscriber.acknowledge_messages_after_processing?
9
+ env.subscriber.run_action_with_filters(env, env.action)
14
10
  end
15
11
  end
16
12
  end
@@ -36,5 +36,15 @@ module ActionSubscriber
36
36
  :recover_from_connection_close => true,
37
37
  }
38
38
  end
39
+
40
+ def self.disconnect!
41
+ CONNECTION_MUTEX.synchronize do
42
+ if @connection && @connection.connected?
43
+ @connection.close
44
+ end
45
+
46
+ @connection = nil
47
+ end
48
+ end
39
49
  end
40
50
  end
@@ -1,3 +1,3 @@
1
1
  module ActionSubscriber
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
@@ -0,0 +1,38 @@
1
+ class InstaSubscriber < ActionSubscriber::Base
2
+ around_filter :whisper
3
+ around_filter :yell
4
+
5
+ def first
6
+ $messages << payload
7
+ end
8
+
9
+ private
10
+
11
+ def whisper
12
+ $messages << :whisper_before
13
+ yield
14
+ $messages << :whisper_after
15
+ end
16
+
17
+ def yell
18
+ $messages << :yell_before
19
+ yield
20
+ $messages << :yell_after
21
+ end
22
+ end
23
+
24
+ describe "subscriber filters", :integration => true do
25
+ let(:connection) { subscriber.connection }
26
+ let(:subscriber) { InstaSubscriber }
27
+
28
+ it "runs multiple around filters" do
29
+ $messages = [] #testing the order of things
30
+ ::ActionSubscriber.auto_subscribe!
31
+ channel = connection.create_channel
32
+ exchange = channel.topic("events")
33
+ exchange.publish("hEY Guyz!", :routing_key => "insta.first")
34
+ sleep 0.1
35
+
36
+ expect($messages).to eq [:whisper_before, :yell_before, "hEY Guyz!", :yell_after, :whisper_after]
37
+ end
38
+ end
@@ -0,0 +1,23 @@
1
+ class GorbyPuffSubscriber < ActionSubscriber::Base
2
+ at_least_once!
3
+
4
+ def grumpy
5
+ $messages << "#{payload}::#{$messages.size}"
6
+ raise RuntimeError.new("what do I do now?") unless $messages.size > 2
7
+ end
8
+ end
9
+
10
+ describe "at_least_once! mode", :integration => true do
11
+ let(:connection) { subscriber.connection }
12
+ let(:subscriber) { GorbyPuffSubscriber }
13
+
14
+ it "retries a failed job until it succeeds" do
15
+ ::ActionSubscriber.auto_subscribe!
16
+ channel = connection.create_channel
17
+ exchange = channel.topic("events")
18
+ exchange.publish("GrumpFace", :routing_key => "gorby_puff.grumpy")
19
+ sleep 0.1
20
+
21
+ expect($messages).to eq Set.new(["GrumpFace::0","GrumpFace::1","GrumpFace::2"])
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ class PokemonSubscriber < ActionSubscriber::Base
2
+ at_most_once!
3
+
4
+ def caught_em_all
5
+ $messages << "DONE::#{$messages.size}"
6
+ raise RuntimeError.new("what do I do now?")
7
+ end
8
+ end
9
+
10
+ describe "at_most_once! mode", :integration => true do
11
+ let(:connection) { subscriber.connection }
12
+ let(:subscriber) { PokemonSubscriber }
13
+
14
+ it "does not retry a failed message" do
15
+ ::ActionSubscriber.auto_subscribe!
16
+ channel = connection.create_channel
17
+ exchange = channel.topic("events")
18
+ exchange.publish("All Pokemon have been caught", :routing_key => "pokemon.caught_em_all")
19
+ sleep 0.1
20
+
21
+ expect($messages.size).to eq 1
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ require "rabbitmq/http/client"
2
+
3
+ class GusSubscriber < ActionSubscriber::Base
4
+ def spoke
5
+ $messages << payload
6
+ end
7
+ end
8
+
9
+ describe "Automatically reconnect on connection failure", :integration => true, :slow => true do
10
+ let(:connection) { subscriber.connection }
11
+ let(:http_client) { RabbitMQ::HTTP::Client.new("http://127.0.0.1:15672") }
12
+ let(:subscriber) { GusSubscriber }
13
+
14
+ it "reconnects when a connection drops" do
15
+ ::ActionSubscriber::auto_subscribe!
16
+ channel = connection.create_channel
17
+ exchange = channel.topic("events")
18
+ exchange.publish("First", :routing_key => "gus.spoke")
19
+ sleep 0.1
20
+
21
+ close_all_connections!
22
+ sleep_until_reconnected
23
+
24
+ exchange.publish("Second", :routing_key => "gus.spoke")
25
+ sleep 0.1
26
+
27
+ expect($messages).to eq(Set.new(["First", "Second"]))
28
+ end
29
+
30
+ def close_all_connections!
31
+ http_client.list_connections.each do |conn_info|
32
+ http_client.close_connection(conn_info.name)
33
+ end
34
+ end
35
+
36
+ def sleep_until_reconnected
37
+ 100.times do
38
+ sleep 0.1
39
+ break if connection.open?
40
+ end
41
+ sleep 0.2
42
+ end
43
+ end
@@ -1,42 +1,48 @@
1
- require 'spec_helper'
2
-
3
1
  class BasicPushSubscriber < ActionSubscriber::Base
4
- BOOKED_MESSAGES = []
5
- CANCELLED_MESSAGES = []
6
-
7
2
  publisher :greg
8
3
 
9
4
  # queue => alice.greg.basic_push.booked
10
5
  # routing_key => greg.basic_push.booked
11
6
  def booked
12
- BOOKED_MESSAGES << payload
7
+ $messages << payload
13
8
  end
14
9
 
15
10
  queue_for :cancelled, "basic.cancelled"
16
11
  routing_key_for :cancelled, "basic.cancelled"
17
12
 
18
13
  def cancelled
19
- CANCELLED_MESSAGES << payload
14
+ $messages << payload
20
15
  end
21
16
  end
22
17
 
23
- describe "A Basic Subscriber using Push API", :integration => true do
18
+ describe "A Basic Subscriber", :integration => true do
24
19
  let(:connection) { subscriber.connection }
25
20
  let(:subscriber) { BasicPushSubscriber }
26
21
 
27
- it "messages are routed to the right place" do
28
- ::ActionSubscriber.start_queues
22
+ context "ActionSubscriber.auto_pop!" do
23
+ it "routes messages to the right place" do
24
+ channel = connection.create_channel
25
+ exchange = channel.topic("events")
26
+ exchange.publish("Ohai Booked", :routing_key => "greg.basic_push.booked")
27
+ exchange.publish("Ohai Cancelled", :routing_key => "basic.cancelled")
28
+ sleep 0.1
29
29
 
30
- channel = connection.create_channel
31
- exchange = channel.topic("events")
32
- exchange.publish("Ohai Booked", :routing_key => "greg.basic_push.booked")
33
- exchange.publish("Ohai Cancelled", :routing_key => "basic.cancelled")
30
+ ::ActionSubscriber.auto_pop!
34
31
 
35
- ::ActionSubscriber.auto_pop!
36
-
37
- expect(subscriber::BOOKED_MESSAGES).to eq(["Ohai Booked"])
38
- expect(subscriber::CANCELLED_MESSAGES).to eq(["Ohai Cancelled"])
32
+ expect($messages).to eq(Set.new(["Ohai Booked", "Ohai Cancelled"]))
33
+ end
34
+ end
39
35
 
40
- connection.close
36
+ context "ActionSubscriber.auto_subscribe!" do
37
+ it "routes messages to the right place" do
38
+ ::ActionSubscriber.auto_subscribe!
39
+ channel = connection.create_channel
40
+ exchange = channel.topic("events")
41
+ exchange.publish("Ohai Booked", :routing_key => "greg.basic_push.booked")
42
+ exchange.publish("Ohai Cancelled", :routing_key => "basic.cancelled")
43
+ sleep 0.1
44
+
45
+ expect($messages).to eq(Set.new(["Ohai Booked", "Ohai Cancelled"]))
46
+ end
41
47
  end
42
48
  end
@@ -0,0 +1,48 @@
1
+ class TwitterSubscriber < ActionSubscriber::Base
2
+ def tweet
3
+ $messages << {
4
+ :decoded => payload,
5
+ :raw => raw_payload,
6
+ }
7
+ end
8
+ end
9
+
10
+
11
+ describe "Payload Decoding", :integration => true do
12
+ let(:connection) { subscriber.connection }
13
+ let(:subscriber) { TwitterSubscriber }
14
+ let(:json_string) { '{"foo": "bar"}' }
15
+
16
+ it "decodes json by default" do
17
+ ::ActionSubscriber.auto_subscribe!
18
+ channel = connection.create_channel
19
+ exchange = channel.topic("events")
20
+ exchange.publish(json_string, :routing_key => "twitter.tweet", :content_type => "application/json")
21
+ sleep 0.1
22
+
23
+ expect($messages).to eq Set.new([{
24
+ :decoded => JSON.parse(json_string),
25
+ :raw => json_string,
26
+ }])
27
+ end
28
+
29
+ context "Custom Decoder" do
30
+ let(:content_type) { "foo/type" }
31
+
32
+ before { ::ActionSubscriber.config.add_decoder(content_type => lambda{ |payload| :foo }) }
33
+ after { ::ActionSubscriber.config.decoder.delete(content_type) }
34
+
35
+ it "it decodes the payload using the custom decoder" do
36
+ ::ActionSubscriber.auto_subscribe!
37
+ channel = connection.create_channel
38
+ exchange = channel.topic("events")
39
+ exchange.publish(json_string, :routing_key => "twitter.tweet", :content_type => content_type)
40
+ sleep 0.1
41
+
42
+ expect($messages).to eq Set.new([{
43
+ :decoded => :foo,
44
+ :raw => json_string,
45
+ }])
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,27 @@
1
+ class BaconSubscriber < ActionSubscriber::Base
2
+ manual_acknowledgement!
3
+
4
+ def served
5
+ $messages << "#{payload}::#{$messages.size}"
6
+ if $messages.size > 2
7
+ acknowledge
8
+ else
9
+ reject
10
+ end
11
+ end
12
+ end
13
+
14
+ describe "Manual Message Acknowledgment", :integration => true do
15
+ let(:connection) { subscriber.connection }
16
+ let(:subscriber) { BaconSubscriber }
17
+
18
+ it "retries rejected messages and stops retrying acknowledged messages" do
19
+ ::ActionSubscriber.auto_subscribe!
20
+ channel = connection.create_channel
21
+ exchange = channel.topic("events")
22
+ exchange.publish("BACON!", :routing_key => "bacon.served")
23
+ sleep 0.1
24
+
25
+ expect($messages).to eq(Set.new(["BACON!::0", "BACON!::1", "BACON!::2"]))
26
+ end
27
+ end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  class TestObject < ActionSubscriber::Base
4
2
  exchange :events
5
3
 
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ::ActionSubscriber::Configuration do
4
2
  describe "default values" do
5
3
  specify { expect(subject.allow_low_priority_methods).to eq(false) }
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ::ActionSubscriber::DSL do
4
2
  let(:subscriber) { Object.new }
5
3
  before { subscriber.extend(::ActionSubscriber::DSL) }
@@ -15,14 +13,6 @@ describe ::ActionSubscriber::DSL do
15
13
  it "returns expected queue subscription options" do
16
14
  expect(subscriber.queue_subscription_options).to eq( :manual_ack => true )
17
15
  end
18
-
19
- it "does not acknowledge messages after processing them" do
20
- expect(subscriber.acknowledge_messages_after_processing?).to eq(false)
21
- end
22
-
23
- it "does not acknowledge messages before processing them" do
24
- expect(subscriber.acknowledge_messages_before_processing?).to eq(false)
25
- end
26
16
  end
27
17
 
28
18
  context "when at_most_once! is set" do
@@ -31,14 +21,6 @@ describe ::ActionSubscriber::DSL do
31
21
  it "acknowledges messages" do
32
22
  expect(subscriber.acknowledge_messages?).to eq(true)
33
23
  end
34
-
35
- it "acknowledges messages before processing them" do
36
- expect(subscriber.acknowledge_messages_before_processing?).to eq(true)
37
- end
38
-
39
- it "does not acknowledge messages after processing them" do
40
- expect(subscriber.acknowledge_messages_after_processing?).to eq(false)
41
- end
42
24
  end
43
25
 
44
26
  context "when at_least_once! is set" do
@@ -47,14 +29,6 @@ describe ::ActionSubscriber::DSL do
47
29
  it "acknowledges messages" do
48
30
  expect(subscriber.acknowledge_messages?).to eq(true)
49
31
  end
50
-
51
- it "does not acknowledge messages before processing them" do
52
- expect(subscriber.acknowledge_messages_before_processing?).to eq(false)
53
- end
54
-
55
- it "acknowledges messages after processing them" do
56
- expect(subscriber.acknowledge_messages_after_processing?).to eq(true)
57
- end
58
32
  end
59
33
 
60
34
  context "when no_acknowledgement! is set" do
@@ -63,28 +37,12 @@ describe ::ActionSubscriber::DSL do
63
37
  it "does not acknowledge messages" do
64
38
  expect(subscriber.acknowledge_messages?).to eq(false)
65
39
  end
66
-
67
- it "does not acknowledge messages after processing them" do
68
- expect(subscriber.acknowledge_messages_after_processing?).to eq(false)
69
- end
70
-
71
- it "does not acknowledge messages before processing them" do
72
- expect(subscriber.acknowledge_messages_before_processing?).to eq(false)
73
- end
74
40
  end
75
41
 
76
42
  context "default" do
77
43
  it "does not acknowledge messages" do
78
44
  expect(subscriber.acknowledge_messages?).to eq(false)
79
45
  end
80
-
81
- it "does not acknowledge messages after processing them" do
82
- expect(subscriber.acknowledge_messages_after_processing?).to eq(false)
83
- end
84
-
85
- it "does not acknowledge messages before processing them" do
86
- expect(subscriber.acknowledge_messages_before_processing?).to eq(false)
87
- end
88
46
  end
89
47
  end
90
48
 
@@ -1,4 +1,3 @@
1
- require 'spec_helper'
2
1
  require 'action_subscriber/middleware/active_record/connection_management'
3
2
 
4
3
  describe ActionSubscriber::Middleware::ActiveRecord::ConnectionManagement do
@@ -1,4 +1,3 @@
1
- require 'spec_helper'
2
1
  require 'action_subscriber/middleware/active_record/query_cache'
3
2
 
4
3
  describe ActionSubscriber::Middleware::ActiveRecord::QueryCache do
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ActionSubscriber::Middleware::Decoder do
4
2
  include_context 'action subscriber middleware env'
5
3
 
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ActionSubscriber::Middleware::Env do
4
2
  let(:channel) { double("channel") }
5
3
  let(:encoded_payload) { 'encoded_payload' }
@@ -1,4 +1,3 @@
1
- require 'spec_helper'
2
1
  require 'action_subscriber/middleware/error_handler'
3
2
 
4
3
  describe ActionSubscriber::Middleware::ErrorHandler do
@@ -19,17 +18,5 @@ describe ActionSubscriber::Middleware::ErrorHandler do
19
18
 
20
19
  subject.call(env)
21
20
  end
22
-
23
- context "when the subscriber was expecting to acknowledge the message" do
24
- before { allow(env.subscriber).to receive(:acknowledge_messages_after_processing?).and_return(true) }
25
-
26
- it "calls the exception handler and rejects the message" do
27
- handler = ::ActionSubscriber.configuration.error_handler
28
- expect(handler).to receive(:call).with(error, env.to_h)
29
- expect(env).to receive(:reject).with(no_args)
30
-
31
- subject.call(env)
32
- end
33
- end
34
21
  end
35
22
  end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ActionSubscriber::Middleware::Router do
4
2
  include_context 'action subscriber middleware env'
5
3
 
@@ -9,16 +7,4 @@ describe ActionSubscriber::Middleware::Router do
9
7
  allow_any_instance_of(env.subscriber).to receive(env.action)
10
8
  subject.call(env)
11
9
  end
12
-
13
- it "acknowledges messages after processing if the subscriber flag is set" do
14
- allow(env.subscriber).to receive(:acknowledge_messages_after_processing?).and_return(true)
15
- expect(env).to receive(:acknowledge)
16
- subject.call(env)
17
- end
18
-
19
- it "acknowledges messages before processing if the subscriber flag is set" do
20
- allow(env.subscriber).to receive(:acknowledge_messages_before_processing?).and_return(true)
21
- expect(env).to receive(:acknowledge)
22
- subject.call(env)
23
- end
24
10
  end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ActionSubscriber::Middleware::Runner do
4
2
  # TODO: Figure out at way to test this...
5
3
  it "adds the router to the top of the stack"
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  TestSubscriber = Class.new(ActionSubscriber::Base) do
4
2
  def updated
5
3
  end
@@ -1,5 +1,3 @@
1
- require 'spec_helper'
2
-
3
1
  describe ::ActionSubscriber::Threadpool do
4
2
  describe "busy?" do
5
3
  context "when the workers are busy" do
data/spec/spec_helper.rb CHANGED
@@ -1,14 +1,8 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
3
 
4
- require 'simplecov'
5
4
  ENV['APP_NAME'] = 'Alice'
6
5
 
7
-
8
- SimpleCov.start do
9
- add_filter 'spec'
10
- end
11
-
12
6
  Bundler.require(:default, :development, :test)
13
7
 
14
8
  require 'action_subscriber'
@@ -23,4 +17,16 @@ RSpec.configure do |config|
23
17
  config.mock_with :rspec do |mocks|
24
18
  mocks.verify_partial_doubles = true
25
19
  end
20
+
21
+ config.before(:each, :integration => true) do
22
+ $messages = Set.new
23
+ ::ActionSubscriber::RabbitConnection.connect!
24
+ ::ActionSubscriber.setup_queues!
25
+ end
26
+ config.after(:each, :integration => true) do
27
+ ::ActionSubscriber::RabbitConnection.disconnect!
28
+ ::ActionSubscriber::Base.inherited_classes.each do |klass|
29
+ klass.instance_variable_set("@_queues", nil)
30
+ end
31
+ end
26
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: action_subscriber
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Stien
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-11-11 00:00:00.000000000 Z
15
+ date: 2015-02-03 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -113,35 +113,35 @@ dependencies:
113
113
  - !ruby/object:Gem::Version
114
114
  version: '0'
115
115
  - !ruby/object:Gem::Dependency
116
- name: rspec
116
+ name: rabbitmq_http_api_client
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - "~>"
120
120
  - !ruby/object:Gem::Version
121
- version: '3.0'
121
+ version: 1.2.0
122
122
  type: :development
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - "~>"
127
127
  - !ruby/object:Gem::Version
128
- version: '3.0'
128
+ version: 1.2.0
129
129
  - !ruby/object:Gem::Dependency
130
- name: rake
130
+ name: rspec
131
131
  requirement: !ruby/object:Gem::Requirement
132
132
  requirements:
133
- - - ">="
133
+ - - "~>"
134
134
  - !ruby/object:Gem::Version
135
- version: '0'
135
+ version: '3.0'
136
136
  type: :development
137
137
  prerelease: false
138
138
  version_requirements: !ruby/object:Gem::Requirement
139
139
  requirements:
140
- - - ">="
140
+ - - "~>"
141
141
  - !ruby/object:Gem::Version
142
- version: '0'
142
+ version: '3.0'
143
143
  - !ruby/object:Gem::Dependency
144
- name: simplecov
144
+ name: rake
145
145
  requirement: !ruby/object:Gem::Requirement
146
146
  requirements:
147
147
  - - ">="
@@ -168,6 +168,7 @@ extra_rdoc_files: []
168
168
  files:
169
169
  - ".gitignore"
170
170
  - ".rspec"
171
+ - ".travis.yml"
171
172
  - Gemfile
172
173
  - LICENSE
173
174
  - LICENSE.txt
@@ -199,7 +200,13 @@ files:
199
200
  - lib/action_subscriber/subscribable.rb
200
201
  - lib/action_subscriber/threadpool.rb
201
202
  - lib/action_subscriber/version.rb
203
+ - spec/integration/around_filters_spec.rb
204
+ - spec/integration/at_least_once_spec.rb
205
+ - spec/integration/at_most_once_spec.rb
206
+ - spec/integration/automatic_reconnect_spec.rb
202
207
  - spec/integration/basic_subscriber_spec.rb
208
+ - spec/integration/decoding_payloads_spec.rb
209
+ - spec/integration/manual_acknowledgement_spec.rb
203
210
  - spec/lib/action_subscriber/base_spec.rb
204
211
  - spec/lib/action_subscriber/configuration_spec.rb
205
212
  - spec/lib/action_subscriber/dsl_spec.rb
@@ -214,7 +221,7 @@ files:
214
221
  - spec/lib/action_subscriber/threadpool_spec.rb
215
222
  - spec/spec_helper.rb
216
223
  - spec/support/user_subscriber.rb
217
- homepage: ''
224
+ homepage: https://github.com/moneydesktop/action_subscriber
218
225
  licenses:
219
226
  - MIT
220
227
  metadata: {}
@@ -234,13 +241,19 @@ required_rubygems_version: !ruby/object:Gem::Requirement
234
241
  version: '0'
235
242
  requirements: []
236
243
  rubyforge_project:
237
- rubygems_version: 2.4.2
244
+ rubygems_version: 2.4.5
238
245
  signing_key:
239
246
  specification_version: 4
240
247
  summary: ActionSubscriber is a DSL that allows a rails app to consume messages from
241
248
  a RabbitMQ broker.
242
249
  test_files:
250
+ - spec/integration/around_filters_spec.rb
251
+ - spec/integration/at_least_once_spec.rb
252
+ - spec/integration/at_most_once_spec.rb
253
+ - spec/integration/automatic_reconnect_spec.rb
243
254
  - spec/integration/basic_subscriber_spec.rb
255
+ - spec/integration/decoding_payloads_spec.rb
256
+ - spec/integration/manual_acknowledgement_spec.rb
244
257
  - spec/lib/action_subscriber/base_spec.rb
245
258
  - spec/lib/action_subscriber/configuration_spec.rb
246
259
  - spec/lib/action_subscriber/dsl_spec.rb