action_subscriber 1.4.0.pre0-java → 1.5.0-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/lib/action_subscriber.rb +44 -10
- data/lib/action_subscriber/babou.rb +2 -4
- data/lib/action_subscriber/base.rb +0 -16
- data/lib/action_subscriber/bunny/subscriber.rb +7 -8
- data/lib/action_subscriber/default_routing.rb +15 -19
- data/lib/action_subscriber/dsl.rb +0 -4
- data/lib/action_subscriber/march_hare/subscriber.rb +7 -8
- data/lib/action_subscriber/route.rb +27 -0
- data/lib/action_subscriber/route_set.rb +35 -0
- data/lib/action_subscriber/router.rb +66 -0
- data/lib/action_subscriber/subscribable.rb +0 -14
- data/lib/action_subscriber/version.rb +1 -1
- data/routing.md +46 -0
- data/spec/lib/action_subscriber/dsl_spec.rb +0 -4
- data/spec/lib/action_subscriber/router_spec.rb +110 -0
- data/spec/spec_helper.rb +2 -3
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3422aaf739a8559ca1fe51edaf9ce6d29452b45
|
4
|
+
data.tar.gz: 88dd7271b35f2675202df563ac0f8c793dee1e0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0dd91629e3d5a50258614402557b7117e7f296d9991ee8c8859bfc4e67225ac2aede2178f3e5e8318f66fb04f0de89b856eac9e5467bac040ef1dfdf5cea11fd
|
7
|
+
data.tar.gz: 4c35a48ca8b97e2b3163b890f43ae5d0d1965d4b63384e625dd1a4e5bf86d0313a650a0b66d4a4cc37d5fa0055946c6cf178c1d7e57eca7346f80957bdc14033
|
data/lib/action_subscriber.rb
CHANGED
@@ -22,6 +22,9 @@ require "action_subscriber/bunny/subscriber"
|
|
22
22
|
require "action_subscriber/march_hare/subscriber"
|
23
23
|
require "action_subscriber/babou"
|
24
24
|
require "action_subscriber/publisher"
|
25
|
+
require "action_subscriber/route"
|
26
|
+
require "action_subscriber/route_set"
|
27
|
+
require "action_subscriber/router"
|
25
28
|
require "action_subscriber/threadpool"
|
26
29
|
require "action_subscriber/base"
|
27
30
|
|
@@ -35,18 +38,14 @@ module ActionSubscriber
|
|
35
38
|
#
|
36
39
|
def self.auto_pop!
|
37
40
|
return if ::ActionSubscriber::Threadpool.busy?
|
38
|
-
|
39
|
-
klass.auto_pop!
|
40
|
-
end
|
41
|
+
route_set.auto_pop!
|
41
42
|
end
|
42
43
|
|
43
44
|
# Loop over all subscribers and register each as
|
44
45
|
# a subscriber.
|
45
46
|
#
|
46
47
|
def self.auto_subscribe!
|
47
|
-
|
48
|
-
klass.auto_subscribe!
|
49
|
-
end
|
48
|
+
route_set.auto_subscribe!
|
50
49
|
end
|
51
50
|
|
52
51
|
def self.configuration
|
@@ -57,14 +56,26 @@ module ActionSubscriber
|
|
57
56
|
yield(configuration) if block_given?
|
58
57
|
end
|
59
58
|
|
59
|
+
def self.draw_routes(&block)
|
60
|
+
routes = Router.draw_routes(&block)
|
61
|
+
@route_set = RouteSet.new(routes)
|
62
|
+
end
|
63
|
+
|
60
64
|
def self.print_subscriptions
|
61
|
-
|
65
|
+
puts configuration.inspect
|
66
|
+
route_set.routes.group_by(&:subscriber).each do |subscriber, routes|
|
67
|
+
puts subscriber.name
|
68
|
+
routes.each do |route|
|
69
|
+
puts " -- method: #{route.action}"
|
70
|
+
puts " -- exchange: #{route.exchange}"
|
71
|
+
puts " -- queue: #{route.queue}"
|
72
|
+
puts " -- routing_key: #{route.routing_key}"
|
73
|
+
end
|
74
|
+
end
|
62
75
|
end
|
63
76
|
|
64
77
|
def self.setup_queues!
|
65
|
-
|
66
|
-
klass.setup_queues!
|
67
|
-
end
|
78
|
+
route_set.setup_queues!
|
68
79
|
end
|
69
80
|
|
70
81
|
def self.start_queues
|
@@ -80,6 +91,10 @@ module ActionSubscriber
|
|
80
91
|
print_subscriptions
|
81
92
|
end
|
82
93
|
|
94
|
+
def self.stop_subscribers!
|
95
|
+
route_set.cancel_consumers!
|
96
|
+
end
|
97
|
+
|
83
98
|
##
|
84
99
|
# Class aliases
|
85
100
|
#
|
@@ -91,6 +106,25 @@ module ActionSubscriber
|
|
91
106
|
config
|
92
107
|
|
93
108
|
::ActiveSupport.run_load_hooks(:action_subscriber, Base)
|
109
|
+
|
110
|
+
##
|
111
|
+
# Private Implementation
|
112
|
+
#
|
113
|
+
def self.route_set
|
114
|
+
@route_set ||= begin
|
115
|
+
puts "DEPRECATION WARNING: We are inferring your routes by looking at your subscribers. This behavior is deprecated and will be removed in version 2.0. Please see the routing guide at https://github.com/mxenabled/action_subscriber/blob/master/routing.md"
|
116
|
+
RouteSet.new(self.send(:default_routes))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
private_class_method :route_set
|
120
|
+
|
121
|
+
def self.default_routes
|
122
|
+
::ActionSubscriber::Base.inherited_classes.flat_map do |klass|
|
123
|
+
klass.routes
|
124
|
+
end
|
125
|
+
end
|
126
|
+
private_class_method :default_routes
|
127
|
+
|
94
128
|
end
|
95
129
|
|
96
130
|
require "action_subscriber/railtie" if defined?(Rails)
|
@@ -81,10 +81,8 @@ module ActionSubscriber
|
|
81
81
|
def self.stop_receving_messages!
|
82
82
|
@shutting_down = true
|
83
83
|
::Thread.new do
|
84
|
-
::ActionSubscriber
|
85
|
-
|
86
|
-
puts "finished cancelling consumers"
|
87
|
-
end
|
84
|
+
::ActionSubscriber.stop_subscribers!
|
85
|
+
puts "stopped all subscribers"
|
88
86
|
end.join
|
89
87
|
end
|
90
88
|
|
@@ -3,11 +3,6 @@ module ActionSubscriber
|
|
3
3
|
extend ::ActionSubscriber::DefaultRouting
|
4
4
|
extend ::ActionSubscriber::DSL
|
5
5
|
extend ::ActionSubscriber::Subscribable
|
6
|
-
if ::RUBY_PLATFORM == "java"
|
7
|
-
extend ::ActionSubscriber::MarchHare::Subscriber
|
8
|
-
else
|
9
|
-
extend ::ActionSubscriber::Bunny::Subscriber
|
10
|
-
end
|
11
6
|
|
12
7
|
##
|
13
8
|
# Private Attributes
|
@@ -49,17 +44,6 @@ module ActionSubscriber
|
|
49
44
|
@_inherited_classes ||= []
|
50
45
|
end
|
51
46
|
|
52
|
-
def self.print_subscriptions
|
53
|
-
puts ::ActionSubscriber.configuration.inspect
|
54
|
-
puts ""
|
55
|
-
|
56
|
-
inherited_classes.each do |klass|
|
57
|
-
puts klass.inspect
|
58
|
-
end
|
59
|
-
|
60
|
-
nil
|
61
|
-
end
|
62
|
-
|
63
47
|
##
|
64
48
|
# Class Aliases
|
65
49
|
#
|
@@ -6,7 +6,6 @@ module ActionSubscriber
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def cancel_consumers!
|
9
|
-
puts "cancelling consumers for #{self}"
|
10
9
|
bunny_consumers.each(&:cancel)
|
11
10
|
end
|
12
11
|
|
@@ -15,8 +14,8 @@ module ActionSubscriber
|
|
15
14
|
# of times we will pop each time we poll the broker
|
16
15
|
times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
|
17
16
|
times_to_pop.times do
|
18
|
-
queues.each do |queue|
|
19
|
-
delivery_info, properties, encoded_payload = queue.pop(queue_subscription_options)
|
17
|
+
queues.each do |route, queue|
|
18
|
+
delivery_info, properties, encoded_payload = queue.pop(route.queue_subscription_options)
|
20
19
|
next unless encoded_payload # empty queue
|
21
20
|
::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
|
22
21
|
properties = {
|
@@ -29,17 +28,17 @@ module ActionSubscriber
|
|
29
28
|
:routing_key => delivery_info.routing_key,
|
30
29
|
:queue => queue.name,
|
31
30
|
}
|
32
|
-
env = ::ActionSubscriber::Middleware::Env.new(
|
31
|
+
env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
|
33
32
|
enqueue_env(env)
|
34
33
|
end
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
37
|
def auto_subscribe!
|
39
|
-
queues.each do |queue|
|
38
|
+
queues.each do |route, queue|
|
40
39
|
channel = queue.channel
|
41
|
-
channel.prefetch(::ActionSubscriber.config.prefetch) if
|
42
|
-
consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !
|
40
|
+
channel.prefetch(::ActionSubscriber.config.prefetch) if route.acknowledgements?
|
41
|
+
consumer = ::Bunny::Consumer.new(channel, queue, channel.generate_consumer_tag, !route.acknowledgements?)
|
43
42
|
consumer.on_delivery do |delivery_info, properties, encoded_payload|
|
44
43
|
::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
|
45
44
|
properties = {
|
@@ -52,7 +51,7 @@ module ActionSubscriber
|
|
52
51
|
:routing_key => delivery_info.routing_key,
|
53
52
|
:queue => queue.name,
|
54
53
|
}
|
55
|
-
env = ::ActionSubscriber::Middleware::Env.new(
|
54
|
+
env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
|
56
55
|
enqueue_env(env)
|
57
56
|
end
|
58
57
|
bunny_consumers << consumer
|
@@ -1,25 +1,21 @@
|
|
1
1
|
module ActionSubscriber
|
2
2
|
module DefaultRouting
|
3
|
-
def
|
4
|
-
@
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def setup_queues!
|
19
|
-
exchange_names.each do |exchange_name|
|
20
|
-
subscribable_methods.each do |method_name|
|
21
|
-
queues << setup_queue!(method_name, exchange_name)
|
3
|
+
def routes
|
4
|
+
@routes ||= begin
|
5
|
+
routes = []
|
6
|
+
exchange_names.each do |exchange_name|
|
7
|
+
subscribable_methods.each do |method_name|
|
8
|
+
routes << ActionSubscriber::Route.new({
|
9
|
+
acknowledgements: acknowledge_messages?,
|
10
|
+
action: method_name,
|
11
|
+
exchange: exchange_name,
|
12
|
+
routing_key: routing_key_name_for_method(method_name),
|
13
|
+
subscriber: self,
|
14
|
+
queue: queue_name_for_method(method_name),
|
15
|
+
})
|
16
|
+
end
|
22
17
|
end
|
18
|
+
routes
|
23
19
|
end
|
24
20
|
end
|
25
21
|
end
|
@@ -59,10 +59,6 @@ module ActionSubscriber
|
|
59
59
|
@_queue_names ||= {}
|
60
60
|
end
|
61
61
|
|
62
|
-
def queue_subscription_options
|
63
|
-
@_queue_subscription_options ||= { :manual_ack => acknowledge_messages? }
|
64
|
-
end
|
65
|
-
|
66
62
|
def remote_application_name(name = nil)
|
67
63
|
@_remote_application_name = name if name
|
68
64
|
@_remote_application_name
|
@@ -2,7 +2,6 @@ module ActionSubscriber
|
|
2
2
|
module MarchHare
|
3
3
|
module Subscriber
|
4
4
|
def cancel_consumers!
|
5
|
-
puts "cancelling consumers for #{self}"
|
6
5
|
march_hare_consumers.each(&:cancel)
|
7
6
|
end
|
8
7
|
|
@@ -11,8 +10,8 @@ module ActionSubscriber
|
|
11
10
|
# of times we will pop each time we poll the broker
|
12
11
|
times_to_pop = [::ActionSubscriber::Threadpool.ready_size, ::ActionSubscriber.config.times_to_pop].min
|
13
12
|
times_to_pop.times do
|
14
|
-
queues.each do |queue|
|
15
|
-
metadata, encoded_payload = queue.pop(queue_subscription_options)
|
13
|
+
queues.each do |route,queue|
|
14
|
+
metadata, encoded_payload = queue.pop(route.queue_subscription_options)
|
16
15
|
next unless encoded_payload
|
17
16
|
::ActiveSupport::Notifications.instrument "popped_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
|
18
17
|
properties = {
|
@@ -25,7 +24,7 @@ module ActionSubscriber
|
|
25
24
|
:routing_key => metadata.routing_key,
|
26
25
|
:queue => queue.name,
|
27
26
|
}
|
28
|
-
env = ::ActionSubscriber::Middleware::Env.new(
|
27
|
+
env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
|
29
28
|
enqueue_env(env)
|
30
29
|
end
|
31
30
|
end
|
@@ -35,9 +34,9 @@ module ActionSubscriber
|
|
35
34
|
end
|
36
35
|
|
37
36
|
def auto_subscribe!
|
38
|
-
queues.each do |queue|
|
39
|
-
queue.channel.prefetch = ::ActionSubscriber.config.prefetch if
|
40
|
-
consumer = queue.subscribe(queue_subscription_options) do |metadata, encoded_payload|
|
37
|
+
queues.each do |route,queue|
|
38
|
+
queue.channel.prefetch = ::ActionSubscriber.config.prefetch if route.acknowledgements?
|
39
|
+
consumer = queue.subscribe(route.queue_subscription_options) do |metadata, encoded_payload|
|
41
40
|
::ActiveSupport::Notifications.instrument "received_event.action_subscriber", :payload_size => encoded_payload.bytesize, :queue => queue.name
|
42
41
|
properties = {
|
43
42
|
:channel => queue.channel,
|
@@ -49,7 +48,7 @@ module ActionSubscriber
|
|
49
48
|
:routing_key => metadata.routing_key,
|
50
49
|
:queue => queue.name,
|
51
50
|
}
|
52
|
-
env = ::ActionSubscriber::Middleware::Env.new(
|
51
|
+
env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
|
53
52
|
enqueue_env(env)
|
54
53
|
end
|
55
54
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActionSubscriber
|
2
|
+
class Route
|
3
|
+
attr_reader :acknowledgements,
|
4
|
+
:action,
|
5
|
+
:exchange,
|
6
|
+
:routing_key,
|
7
|
+
:subscriber,
|
8
|
+
:queue
|
9
|
+
|
10
|
+
def initialize(attributes)
|
11
|
+
@acknowledgements = attributes.fetch(:acknowledgements)
|
12
|
+
@action = attributes.fetch(:action)
|
13
|
+
@exchange = attributes.fetch(:exchange).to_s
|
14
|
+
@routing_key = attributes.fetch(:routing_key)
|
15
|
+
@subscriber = attributes.fetch(:subscriber)
|
16
|
+
@queue = attributes.fetch(:queue)
|
17
|
+
end
|
18
|
+
|
19
|
+
def acknowledgements?
|
20
|
+
@acknowledgements
|
21
|
+
end
|
22
|
+
|
23
|
+
def queue_subscription_options
|
24
|
+
{ :manual_ack => acknowledgements? }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ActionSubscriber
|
2
|
+
class RouteSet
|
3
|
+
if ::RUBY_PLATFORM == "java"
|
4
|
+
include ::ActionSubscriber::MarchHare::Subscriber
|
5
|
+
else
|
6
|
+
include ::ActionSubscriber::Bunny::Subscriber
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_reader :routes
|
10
|
+
|
11
|
+
def initialize(routes)
|
12
|
+
@routes = routes
|
13
|
+
end
|
14
|
+
|
15
|
+
def setup_queues!
|
16
|
+
routes.each do |route|
|
17
|
+
queues[route] = setup_queue(route)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def queues
|
24
|
+
@queues ||= {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_queue(route)
|
28
|
+
channel = ::ActionSubscriber::RabbitConnection.subscriber_connection.create_channel
|
29
|
+
exchange = channel.topic(route.exchange)
|
30
|
+
queue = channel.queue(route.queue)
|
31
|
+
queue.bind(exchange, :routing_key => route.routing_key)
|
32
|
+
queue
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module ActionSubscriber
|
2
|
+
class Router
|
3
|
+
def self.draw_routes(&block)
|
4
|
+
router = self.new
|
5
|
+
router.instance_eval(&block)
|
6
|
+
router.routes
|
7
|
+
end
|
8
|
+
|
9
|
+
DEFAULT_SETTINGS = {
|
10
|
+
:acknowledgements => false,
|
11
|
+
:exchange => "events",
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def default_routing_key_for(route_settings)
|
15
|
+
[
|
16
|
+
route_settings[:publisher],
|
17
|
+
resource_name(route_settings),
|
18
|
+
route_settings[:action].to_s,
|
19
|
+
].compact.join(".")
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_queue_for(route_settings)
|
23
|
+
[
|
24
|
+
local_application_name,
|
25
|
+
route_settings[:publisher],
|
26
|
+
resource_name(route_settings),
|
27
|
+
route_settings[:action].to_s,
|
28
|
+
].compact.join(".")
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_routes_for(subscriber)
|
32
|
+
subscriber.routes.each do |route|
|
33
|
+
routes << route
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def resource_name(route_settings)
|
38
|
+
route_settings[:subscriber].name.underscore.gsub(/_subscriber/, "").to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def route(subscriber, action, options = {})
|
42
|
+
route_settings = DEFAULT_SETTINGS.merge(options).merge(:subscriber => subscriber, :action => action)
|
43
|
+
route_settings[:routing_key] ||= default_routing_key_for(route_settings)
|
44
|
+
route_settings[:queue] ||= default_queue_for(route_settings)
|
45
|
+
routes << Route.new(route_settings)
|
46
|
+
end
|
47
|
+
|
48
|
+
def routes
|
49
|
+
@routes ||= []
|
50
|
+
end
|
51
|
+
|
52
|
+
def local_application_name
|
53
|
+
@_local_application_name ||= begin
|
54
|
+
local_application_name = case
|
55
|
+
when ENV['APP_NAME'] then
|
56
|
+
ENV['APP_NAME'].to_s.dup
|
57
|
+
when defined?(::Rails) then
|
58
|
+
::Rails.application.class.parent_name.dup
|
59
|
+
else
|
60
|
+
raise "Define an application name (ENV['APP_NAME'])"
|
61
|
+
end
|
62
|
+
local_application_name.downcase
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -46,20 +46,6 @@ module ActionSubscriber
|
|
46
46
|
@_local_application_name
|
47
47
|
end
|
48
48
|
|
49
|
-
def inspect
|
50
|
-
inspection_string = "#{self.name}\n"
|
51
|
-
exchange_names.each do |exchange_name|
|
52
|
-
inspection_string << " -- exchange: #{exchange_name}\n"
|
53
|
-
subscribable_methods.each do |method|
|
54
|
-
inspection_string << " -- method: #{method}\n"
|
55
|
-
inspection_string << " -- queue: #{queue_names[method]}\n"
|
56
|
-
inspection_string << " -- routing_key: #{routing_key_names[method]}\n"
|
57
|
-
inspection_string << "\n"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
return inspection_string
|
61
|
-
end
|
62
|
-
|
63
49
|
# Build the `queue` for a given method.
|
64
50
|
#
|
65
51
|
# If the queue name is not set, the queue name is
|
data/routing.md
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# Routing In ActionSubscriber
|
2
|
+
|
3
|
+
ActionSubscriber used to automatically discover all your subscribers and infer all their routes based on a default set of rules<sup>[1](#footnotes)</sup>. As of ActionSubscriber `1.5.0` this behavior is deprecated in favor of having the application draw its routes explicitly.
|
4
|
+
|
5
|
+
## The Simple Upgrade Path
|
6
|
+
|
7
|
+
The simplest way to draw your routes is to create a `config/initializers/action_subscriber.rb` file and ask the router to setup default routes like this:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
::ActionSubscriber.draw_routes do
|
11
|
+
default_routes_for ::UserSubscriber
|
12
|
+
default_routes_for ::NotificationSubscriber
|
13
|
+
end
|
14
|
+
```
|
15
|
+
|
16
|
+
This is the easiest migration path for existing users to follow, but it doesn't allow for things like mixing which exchange you are subscribing to between different actions.
|
17
|
+
|
18
|
+
## Custom Routes
|
19
|
+
|
20
|
+
You can also specify custom routes for your subscribers when you want more flexibility.
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
::ActionSubscriber.draw_routes do
|
24
|
+
default_routes_for ::UserSubscriber
|
25
|
+
|
26
|
+
route ::NotificationSubscriber, :created, :publisher => :newman, :exchange => :events
|
27
|
+
route ::NotificationSubscriber, :send, :publisher => :newman, :exchange => :action
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## Options For Routes
|
32
|
+
|
33
|
+
The `route` method supports the following options:
|
34
|
+
|
35
|
+
* `acknowledgements` this toggles whether this route is expected to provide an acknowledgment (default `false`)
|
36
|
+
* This is the equivalent of calling `at_most_once!`, `at_least_once!` or `manual_acknowledgement!` in your subscriber class
|
37
|
+
* `exchange` specify which exchange you expect messages to be published to (default `"events"`)
|
38
|
+
* This is the equivalent of calling `exchange :actions` in your subscriber
|
39
|
+
* `publisher` this will prefix your queue and routing key with the publishers name
|
40
|
+
* This is the equivalent of puting `publisher :foo` in your subscriber
|
41
|
+
* `queue` specifies which queue you will subscribe to rather than letting ActionSubscriber infer it from the name of the subscriber and action
|
42
|
+
* `routing_key` specifies the routing key that will be bound to your queue
|
43
|
+
|
44
|
+
<h3 id="footnotes">Footnotes</h3>
|
45
|
+
|
46
|
+
* __1__ the old behavior of discovering and inferring routes for subscribers will be supported until the 2.0 version of ActionSubscriber. When no routes are drawn before calling `setup_queues!` we will print a deprecation warning and infer the routes for you.
|
@@ -9,10 +9,6 @@ describe ::ActionSubscriber::DSL do
|
|
9
9
|
it "acknowledges messages" do
|
10
10
|
expect(subscriber.acknowledge_messages?).to eq(true)
|
11
11
|
end
|
12
|
-
|
13
|
-
it "returns expected queue subscription options" do
|
14
|
-
expect(subscriber.queue_subscription_options).to eq( :manual_ack => true )
|
15
|
-
end
|
16
12
|
end
|
17
13
|
|
18
14
|
context "when at_most_once! is set" do
|
@@ -0,0 +1,110 @@
|
|
1
|
+
describe ActionSubscriber::Router do
|
2
|
+
class FakeSubscriber; end
|
3
|
+
|
4
|
+
it "can specify basic routes" do
|
5
|
+
routes = described_class.draw_routes do
|
6
|
+
route FakeSubscriber, :foo
|
7
|
+
end
|
8
|
+
|
9
|
+
expect(routes.first.acknowledgements).to eq(false)
|
10
|
+
expect(routes.first.action).to eq(:foo)
|
11
|
+
expect(routes.first.exchange).to eq("events")
|
12
|
+
expect(routes.first.routing_key).to eq("fake.foo")
|
13
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
14
|
+
expect(routes.first.queue).to eq("alice.fake.foo")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can specify a publisher" do
|
18
|
+
routes = described_class.draw_routes do
|
19
|
+
route FakeSubscriber, :bluff, :publisher => :amigo
|
20
|
+
end
|
21
|
+
|
22
|
+
expect(routes.first.acknowledgements).to eq(false)
|
23
|
+
expect(routes.first.action).to eq(:bluff)
|
24
|
+
expect(routes.first.exchange).to eq("events")
|
25
|
+
expect(routes.first.routing_key).to eq("amigo.fake.bluff")
|
26
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
27
|
+
expect(routes.first.queue).to eq("alice.amigo.fake.bluff")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "can specify an exchange" do
|
31
|
+
routes = described_class.draw_routes do
|
32
|
+
route FakeSubscriber, :crashed, :exchange => :actions
|
33
|
+
end
|
34
|
+
|
35
|
+
expect(routes.first.acknowledgements).to eq(false)
|
36
|
+
expect(routes.first.action).to eq(:crashed)
|
37
|
+
expect(routes.first.exchange).to eq("actions")
|
38
|
+
expect(routes.first.routing_key).to eq("fake.crashed")
|
39
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
40
|
+
expect(routes.first.queue).to eq("alice.fake.crashed")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "can specify acknowledgements" do
|
44
|
+
routes = described_class.draw_routes do
|
45
|
+
route FakeSubscriber, :foo, :acknowledgements => true
|
46
|
+
end
|
47
|
+
|
48
|
+
expect(routes.first.acknowledgements).to eq(true)
|
49
|
+
expect(routes.first.action).to eq(:foo)
|
50
|
+
expect(routes.first.exchange).to eq("events")
|
51
|
+
expect(routes.first.routing_key).to eq("fake.foo")
|
52
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
53
|
+
expect(routes.first.queue).to eq("alice.fake.foo")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "can specify the queue" do
|
57
|
+
routes = described_class.draw_routes do
|
58
|
+
route FakeSubscriber, :foo, :publisher => "russell", :queue => "i-am-your-father"
|
59
|
+
end
|
60
|
+
|
61
|
+
expect(routes.first.acknowledgements).to eq(false)
|
62
|
+
expect(routes.first.action).to eq(:foo)
|
63
|
+
expect(routes.first.exchange).to eq("events")
|
64
|
+
expect(routes.first.routing_key).to eq("russell.fake.foo")
|
65
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
66
|
+
expect(routes.first.queue).to eq("i-am-your-father")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "can specify the routing key" do
|
70
|
+
routes = described_class.draw_routes do
|
71
|
+
route FakeSubscriber, :foo, :publisher => "russell", :routing_key => "make.it.so"
|
72
|
+
end
|
73
|
+
|
74
|
+
expect(routes.first.acknowledgements).to eq(false)
|
75
|
+
expect(routes.first.action).to eq(:foo)
|
76
|
+
expect(routes.first.exchange).to eq("events")
|
77
|
+
expect(routes.first.routing_key).to eq("make.it.so")
|
78
|
+
expect(routes.first.subscriber).to eq(FakeSubscriber)
|
79
|
+
expect(routes.first.queue).to eq("alice.russell.fake.foo")
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can infer routes based on the default routing rules" do
|
83
|
+
class SparkleSubscriber < ::ActionSubscriber::Base
|
84
|
+
at_most_once!
|
85
|
+
publisher :tommy
|
86
|
+
exchange :party
|
87
|
+
|
88
|
+
def bright; end
|
89
|
+
def dim; end
|
90
|
+
end
|
91
|
+
|
92
|
+
routes = described_class.draw_routes do
|
93
|
+
default_routes_for SparkleSubscriber
|
94
|
+
end
|
95
|
+
|
96
|
+
expect(routes.size).to eq(2)
|
97
|
+
expect(routes.first.acknowledgements).to eq(true)
|
98
|
+
expect(routes.first.action).to eq(:bright)
|
99
|
+
expect(routes.first.exchange).to eq("party")
|
100
|
+
expect(routes.first.routing_key).to eq("tommy.sparkle.bright")
|
101
|
+
expect(routes.first.subscriber).to eq(SparkleSubscriber)
|
102
|
+
expect(routes.first.queue).to eq("alice.tommy.sparkle.bright")
|
103
|
+
expect(routes.last.acknowledgements).to eq(true)
|
104
|
+
expect(routes.last.action).to eq(:dim)
|
105
|
+
expect(routes.last.exchange).to eq("party")
|
106
|
+
expect(routes.last.routing_key).to eq("tommy.sparkle.dim")
|
107
|
+
expect(routes.last.subscriber).to eq(SparkleSubscriber)
|
108
|
+
expect(routes.last.queue).to eq("alice.tommy.sparkle.dim")
|
109
|
+
end
|
110
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -24,10 +24,9 @@ RSpec.configure do |config|
|
|
24
24
|
::ActionSubscriber.setup_queues!
|
25
25
|
end
|
26
26
|
config.after(:each, :integration => true) do
|
27
|
+
::ActionSubscriber.stop_subscribers!
|
27
28
|
::ActionSubscriber::RabbitConnection.subscriber_disconnect!
|
28
|
-
::ActionSubscriber
|
29
|
-
klass.instance_variable_set("@_queues", nil)
|
30
|
-
end
|
29
|
+
::ActionSubscriber.instance_variable_set("@route_set", nil)
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
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.
|
4
|
+
version: 1.5.0
|
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: 2015-
|
15
|
+
date: 2015-11-20 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
requirement: !ruby/object:Gem::Requirement
|
@@ -214,10 +214,14 @@ files:
|
|
214
214
|
- lib/action_subscriber/publisher.rb
|
215
215
|
- lib/action_subscriber/rabbit_connection.rb
|
216
216
|
- lib/action_subscriber/railtie.rb
|
217
|
+
- lib/action_subscriber/route.rb
|
218
|
+
- lib/action_subscriber/route_set.rb
|
219
|
+
- lib/action_subscriber/router.rb
|
217
220
|
- lib/action_subscriber/rspec.rb
|
218
221
|
- lib/action_subscriber/subscribable.rb
|
219
222
|
- lib/action_subscriber/threadpool.rb
|
220
223
|
- lib/action_subscriber/version.rb
|
224
|
+
- routing.md
|
221
225
|
- spec/integration/around_filters_spec.rb
|
222
226
|
- spec/integration/at_least_once_spec.rb
|
223
227
|
- spec/integration/at_most_once_spec.rb
|
@@ -237,6 +241,7 @@ files:
|
|
237
241
|
- spec/lib/action_subscriber/middleware/router_spec.rb
|
238
242
|
- spec/lib/action_subscriber/middleware/runner_spec.rb
|
239
243
|
- spec/lib/action_subscriber/publisher_spec.rb
|
244
|
+
- spec/lib/action_subscriber/router_spec.rb
|
240
245
|
- spec/lib/action_subscriber/subscribable_spec.rb
|
241
246
|
- spec/lib/action_subscriber/threadpool_spec.rb
|
242
247
|
- spec/spec_helper.rb
|
@@ -256,12 +261,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
256
261
|
version: '0'
|
257
262
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
258
263
|
requirements:
|
259
|
-
- - "
|
264
|
+
- - ">="
|
260
265
|
- !ruby/object:Gem::Version
|
261
|
-
version:
|
266
|
+
version: '0'
|
262
267
|
requirements: []
|
263
268
|
rubyforge_project:
|
264
|
-
rubygems_version: 2.
|
269
|
+
rubygems_version: 2.5.0
|
265
270
|
signing_key:
|
266
271
|
specification_version: 4
|
267
272
|
summary: ActionSubscriber is a DSL that allows a rails app to consume messages from a RabbitMQ broker.
|
@@ -285,6 +290,7 @@ test_files:
|
|
285
290
|
- spec/lib/action_subscriber/middleware/router_spec.rb
|
286
291
|
- spec/lib/action_subscriber/middleware/runner_spec.rb
|
287
292
|
- spec/lib/action_subscriber/publisher_spec.rb
|
293
|
+
- spec/lib/action_subscriber/router_spec.rb
|
288
294
|
- spec/lib/action_subscriber/subscribable_spec.rb
|
289
295
|
- spec/lib/action_subscriber/threadpool_spec.rb
|
290
296
|
- spec/spec_helper.rb
|