action_subscriber 1.0.3-java → 1.0.4-java
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.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +12 -0
- data/Gemfile +0 -1
- data/README.md +10 -4
- data/action_subscriber.gemspec +2 -2
- data/lib/action_subscriber/base.rb +13 -0
- data/lib/action_subscriber/dsl.rb +16 -6
- data/lib/action_subscriber/middleware/error_handler.rb +0 -1
- data/lib/action_subscriber/middleware/router.rb +1 -5
- data/lib/action_subscriber/rabbit_connection.rb +10 -0
- data/lib/action_subscriber/version.rb +1 -1
- data/spec/integration/around_filters_spec.rb +38 -0
- data/spec/integration/at_least_once_spec.rb +23 -0
- data/spec/integration/at_most_once_spec.rb +23 -0
- data/spec/integration/automatic_reconnect_spec.rb +43 -0
- data/spec/integration/basic_subscriber_spec.rb +25 -19
- data/spec/integration/decoding_payloads_spec.rb +48 -0
- data/spec/integration/manual_acknowledgement_spec.rb +27 -0
- data/spec/lib/action_subscriber/base_spec.rb +0 -2
- data/spec/lib/action_subscriber/configuration_spec.rb +0 -2
- data/spec/lib/action_subscriber/dsl_spec.rb +0 -42
- data/spec/lib/action_subscriber/middleware/active_record/connection_management_spec.rb +0 -1
- data/spec/lib/action_subscriber/middleware/active_record/query_cache_spec.rb +0 -1
- data/spec/lib/action_subscriber/middleware/decoder_spec.rb +0 -2
- data/spec/lib/action_subscriber/middleware/env_spec.rb +0 -2
- data/spec/lib/action_subscriber/middleware/error_handler_spec.rb +0 -13
- data/spec/lib/action_subscriber/middleware/router_spec.rb +0 -14
- data/spec/lib/action_subscriber/middleware/runner_spec.rb +0 -2
- data/spec/lib/action_subscriber/subscribable_spec.rb +0 -2
- data/spec/lib/action_subscriber/threadpool_spec.rb +0 -2
- data/spec/spec_helper.rb +12 -6
- metadata +25 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b4d9b95b805582ecb7730fabdfa3d99adac708f2
|
4
|
+
data.tar.gz: 2a016a851347d77f3c2ebdbf83c6860455e0599b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98a8fbb5c315e381cf079a3e909991e1be22f2ef644e2204727356c85d509a01faf50496e58281d0b6f157e2eda89f3d148f549427372e62f9baf830dea1cba6
|
7
|
+
data.tar.gz: 3aec2d0022224cb122acc2fd43d53513aa14bf491bc15076493aa4b77c80a72744e4cb345d87f5996fcae0fc0666a3abbfec7243af804520e2d483afa94537a2
|
data/.rspec
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
[](https://travis-ci.org/moneydesktop/action_subscriber)
|
2
|
+
[](https://codeclimate.com/github/moneydesktop/action_subscriber)
|
3
|
+
[](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.
|
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.
|
81
|
-
* config.
|
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
|
----------------------
|
data/action_subscriber.gemspec
CHANGED
@@ -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
|
-
|
5
|
+
around_filter :_at_least_once_filter
|
6
6
|
end
|
7
7
|
|
8
8
|
def at_most_once!
|
9
9
|
@_acknowledge_messages = true
|
10
|
-
|
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
|
18
|
-
|
17
|
+
def around_filter(filter_method)
|
18
|
+
around_filters << filter_method
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
|
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
|
@@ -6,11 +6,7 @@ module ActionSubscriber
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def call(env)
|
9
|
-
|
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
|
@@ -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
|
-
|
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
|
-
|
14
|
+
$messages << payload
|
20
15
|
end
|
21
16
|
end
|
22
17
|
|
23
|
-
describe "A Basic Subscriber
|
18
|
+
describe "A Basic Subscriber", :integration => true do
|
24
19
|
let(:connection) { subscriber.connection }
|
25
20
|
let(:subscriber) { BasicPushSubscriber }
|
26
21
|
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
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
|
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/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
|
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.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: java
|
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:
|
15
|
+
date: 2015-02-10 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,36 +117,36 @@ dependencies:
|
|
117
117
|
requirements:
|
118
118
|
- - ~>
|
119
119
|
- !ruby/object:Gem::Version
|
120
|
-
version:
|
121
|
-
name:
|
120
|
+
version: 1.2.0
|
121
|
+
name: rabbitmq_http_api_client
|
122
122
|
prerelease: false
|
123
123
|
type: :development
|
124
124
|
version_requirements: !ruby/object:Gem::Requirement
|
125
125
|
requirements:
|
126
126
|
- - ~>
|
127
127
|
- !ruby/object:Gem::Version
|
128
|
-
version:
|
128
|
+
version: 1.2.0
|
129
129
|
- !ruby/object:Gem::Dependency
|
130
130
|
requirement: !ruby/object:Gem::Requirement
|
131
131
|
requirements:
|
132
|
-
- -
|
132
|
+
- - ~>
|
133
133
|
- !ruby/object:Gem::Version
|
134
|
-
version: '0'
|
135
|
-
name:
|
134
|
+
version: '3.0'
|
135
|
+
name: rspec
|
136
136
|
prerelease: false
|
137
137
|
type: :development
|
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
144
|
requirement: !ruby/object:Gem::Requirement
|
145
145
|
requirements:
|
146
146
|
- - '>='
|
147
147
|
- !ruby/object:Gem::Version
|
148
148
|
version: '0'
|
149
|
-
name:
|
149
|
+
name: rake
|
150
150
|
prerelease: false
|
151
151
|
type: :development
|
152
152
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -167,6 +167,7 @@ extra_rdoc_files: []
|
|
167
167
|
files:
|
168
168
|
- .gitignore
|
169
169
|
- .rspec
|
170
|
+
- .travis.yml
|
170
171
|
- Gemfile
|
171
172
|
- LICENSE
|
172
173
|
- LICENSE.txt
|
@@ -198,7 +199,13 @@ files:
|
|
198
199
|
- lib/action_subscriber/subscribable.rb
|
199
200
|
- lib/action_subscriber/threadpool.rb
|
200
201
|
- lib/action_subscriber/version.rb
|
202
|
+
- spec/integration/around_filters_spec.rb
|
203
|
+
- spec/integration/at_least_once_spec.rb
|
204
|
+
- spec/integration/at_most_once_spec.rb
|
205
|
+
- spec/integration/automatic_reconnect_spec.rb
|
201
206
|
- spec/integration/basic_subscriber_spec.rb
|
207
|
+
- spec/integration/decoding_payloads_spec.rb
|
208
|
+
- spec/integration/manual_acknowledgement_spec.rb
|
202
209
|
- spec/lib/action_subscriber/base_spec.rb
|
203
210
|
- spec/lib/action_subscriber/configuration_spec.rb
|
204
211
|
- spec/lib/action_subscriber/dsl_spec.rb
|
@@ -213,7 +220,7 @@ files:
|
|
213
220
|
- spec/lib/action_subscriber/threadpool_spec.rb
|
214
221
|
- spec/spec_helper.rb
|
215
222
|
- spec/support/user_subscriber.rb
|
216
|
-
homepage:
|
223
|
+
homepage: https://github.com/moneydesktop/action_subscriber
|
217
224
|
licenses:
|
218
225
|
- MIT
|
219
226
|
metadata: {}
|
@@ -238,7 +245,13 @@ signing_key:
|
|
238
245
|
specification_version: 4
|
239
246
|
summary: ActionSubscriber is a DSL that allows a rails app to consume messages from a RabbitMQ broker.
|
240
247
|
test_files:
|
248
|
+
- spec/integration/around_filters_spec.rb
|
249
|
+
- spec/integration/at_least_once_spec.rb
|
250
|
+
- spec/integration/at_most_once_spec.rb
|
251
|
+
- spec/integration/automatic_reconnect_spec.rb
|
241
252
|
- spec/integration/basic_subscriber_spec.rb
|
253
|
+
- spec/integration/decoding_payloads_spec.rb
|
254
|
+
- spec/integration/manual_acknowledgement_spec.rb
|
242
255
|
- spec/lib/action_subscriber/base_spec.rb
|
243
256
|
- spec/lib/action_subscriber/configuration_spec.rb
|
244
257
|
- spec/lib/action_subscriber/dsl_spec.rb
|