action_subscriber 3.0.2-java → 4.0.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/README.md +41 -7
- data/action_subscriber.gemspec +0 -1
- data/bin/action_subscriber +7 -15
- data/lib/action_subscriber.rb +10 -49
- data/lib/action_subscriber/babou.rb +7 -43
- data/lib/action_subscriber/base.rb +0 -70
- data/lib/action_subscriber/bunny/subscriber.rb +43 -41
- data/lib/action_subscriber/configuration.rb +1 -7
- data/lib/action_subscriber/dsl.rb +95 -3
- data/lib/action_subscriber/march_hare/subscriber.rb +41 -51
- data/lib/action_subscriber/route.rb +0 -1
- data/lib/action_subscriber/route_set.rb +5 -19
- data/lib/action_subscriber/version.rb +1 -1
- data/spec/integration/around_filters_spec.rb +1 -1
- data/spec/integration/at_least_once_spec.rb +1 -1
- data/spec/integration/at_most_once_spec.rb +45 -9
- data/spec/integration/automatic_reconnect_spec.rb +28 -28
- data/spec/integration/basic_subscriber_spec.rb +5 -18
- data/spec/integration/custom_actions_spec.rb +1 -1
- data/spec/integration/custom_headers_spec.rb +3 -11
- data/spec/integration/decoding_payloads_spec.rb +2 -2
- data/spec/integration/manual_acknowledgement_spec.rb +1 -1
- data/spec/integration/multiple_connections_spec.rb +1 -1
- data/spec/lib/action_subscriber/configuration_spec.rb +0 -3
- data/spec/spec_helper.rb +2 -2
- metadata +3 -22
- data/lib/action_subscriber/threadpool.rb +0 -62
- data/spec/integration/multiple_threadpools_spec.rb +0 -29
- data/spec/lib/action_subscriber/threadpool_spec.rb +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21826dc618d8f6772a1d2a087dd4c638a90d2f48
|
4
|
+
data.tar.gz: c9ee56ec1babee1d5197ac54179e939e7896881b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 980e4a792b42fa51b92088f6a494b00f7d0fe2ca51aec512235efd00b756be6a0d0fcbe1c6902919cfcef109f6b224e4c4a70f40fb5955786c9c9b81ad75953a
|
7
|
+
data.tar.gz: 155393e3b5e6a7625c8da0af08369c1bdfab91ad4ac011e47935181d49377dae0c1d962158419f6f78384efe7a09102e85f46fbe38df8be8c9f7f5a8f0b71afd
|
data/README.md
CHANGED
@@ -13,6 +13,38 @@ I test on Ruby 2.2.1 and Jruby 9.x. MRI 1.9 and jRuby 1.7 are still supported.
|
|
13
13
|
|
14
14
|
If you want to use MRI 1.9 you will need to lock down the `amq-protocol` and `bunny` gems to `< 2.0` since they both require ruby 2.0+.
|
15
15
|
|
16
|
+
Migrating from ActionSubscriber 3.X or earlier
|
17
|
+
----------------------------------------------
|
18
|
+
|
19
|
+
If you were using the `--mode=pop` from the 2.X or 3.X version of ActionSubscriber you can get the same sort of behavior by drawing your routes like this:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
::ActionSubscriber.draw_routes do
|
23
|
+
# instead of creating custom threadpools you set the threadpool size of your connection here in the routes
|
24
|
+
# you can set the threadpool size for the default connection via the `::ActionSubscriber.configuration.threadpool_size = 16`
|
25
|
+
route UserSubscriber, :created,
|
26
|
+
:prefetch => 1,
|
27
|
+
:concurrency => 16,
|
28
|
+
:acknowledgements => true
|
29
|
+
|
30
|
+
# in user_subscriber.rb make sure to set `at_most_once!` like this
|
31
|
+
#
|
32
|
+
# class UserSubscriber < ::ActionSubscriber::Base
|
33
|
+
# at_most_once!
|
34
|
+
# end
|
35
|
+
|
36
|
+
# If you were previously using custom threadpools for different routes you can mimic that behavior by opening multiple connections
|
37
|
+
connection(:slow_work, :threadpool_size => 32) do
|
38
|
+
route UserSubscriber, :created,
|
39
|
+
:prefetch => 1,
|
40
|
+
:concurrency => 32,
|
41
|
+
:acknowledgements => true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
That will give you a similar behavior to the old `--mode=pop` where messages polled from the server, but with reduced latency.
|
47
|
+
|
16
48
|
Supported Message Types
|
17
49
|
-----------------
|
18
50
|
ActionSubscriber support JSON and plain text out of the box, but you can easily
|
@@ -51,12 +83,10 @@ Now you can start your subscriber process with:
|
|
51
83
|
|
52
84
|
|
53
85
|
```
|
54
|
-
$ bundle exec action_subscriber start
|
86
|
+
$ bundle exec action_subscriber start
|
55
87
|
```
|
56
88
|
|
57
|
-
This will
|
58
|
-
|
59
|
-
You can also start in `--mode=pop` where your process will poll the broker for messages.
|
89
|
+
This will connect your subscribers to the rabbitmq broker and allow it to push messages down to your subscribers.
|
60
90
|
|
61
91
|
Configuration
|
62
92
|
-----------------
|
@@ -76,16 +106,18 @@ Other configuration options include :
|
|
76
106
|
* config.error_handler - handle error like you want to handle them!
|
77
107
|
* config.heartbeat - number of seconds between hearbeats (default 5) [see bunny documentation for more details](http://rubybunny.info/articles/connecting.html)
|
78
108
|
* config.hosts - an array of hostnames in your cluster (ie `["rabbit1.myapp.com", "rabbit2.myapp.com"]`)
|
79
|
-
* config.pop_interval - how long to wait between polling for messages in `--mode=pop`. It should be a number of milliseconds
|
80
109
|
* config.threadpool_size - set the number of threads availiable to action_subscriber
|
81
110
|
* config.timeout - how many seconds to allow rabbit to respond before timing out
|
82
|
-
* config.times_to_pop - when using RabbitMQ's pull API, the number of messages we will grab each time we pool the broker
|
83
111
|
|
84
112
|
Message Acknowledgment
|
85
113
|
----------------------
|
86
114
|
### no_acknolwedgement!
|
87
115
|
|
88
116
|
This mode is the default. Rabbit is told to not expect any message acknowledgements so messages will be lost if an error occurs.
|
117
|
+
This also allows the broker to send messages as quickly as it wants down to your subscriber.
|
118
|
+
|
119
|
+
> Warning: If messages arrive very quickly this could cause your process to crash as your memory fills up with unprocessed message.
|
120
|
+
> We highly recommend you use `at_least_once!` mode to provide a throttle so the broker does not overwhelm your process with messages.
|
89
121
|
|
90
122
|
### manual_acknowledgement!
|
91
123
|
|
@@ -97,7 +129,9 @@ Rabbit is told to expect message acknowledgements, but sending the acknowledgeme
|
|
97
129
|
|
98
130
|
### at_least_once!
|
99
131
|
|
100
|
-
Rabbit is told to expect message acknowledgements, but sending the acknowledgement is left up to ActionSubscriber.
|
132
|
+
Rabbit is told to expect message acknowledgements, but sending the acknowledgement is left up to ActionSubscriber.
|
133
|
+
We send the acknowledgement right after calling your subscriber.
|
134
|
+
If an error is raised your message will be retried on a sent back to rabbitmq and retried on an exponential backoff schedule.
|
101
135
|
|
102
136
|
Testing
|
103
137
|
-----------------
|
data/action_subscriber.gemspec
CHANGED
data/bin/action_subscriber
CHANGED
@@ -7,7 +7,6 @@ module ActionSubscriber
|
|
7
7
|
class CLI < ::Thor
|
8
8
|
class_option :allow_low_priority_methods, :type => :boolean, :desc => "subscribe to low priority queues in addition to the normal queues", :default => false
|
9
9
|
class_option :app, :default => "./config/environment.rb"
|
10
|
-
class_option :mode
|
11
10
|
class_option :host
|
12
11
|
class_option :hosts
|
13
12
|
class_option :prefetch, :type => :numeric, :desc => "how many messages to hold in the local queue in subscribe mode"
|
@@ -36,14 +35,7 @@ module ActionSubscriber
|
|
36
35
|
# Require action_subscriber if the application did not.
|
37
36
|
require "action_subscriber"
|
38
37
|
|
39
|
-
|
40
|
-
when /pop/i then
|
41
|
-
::ActionSubscriber::Babou.auto_pop!
|
42
|
-
when /subscribe/i then
|
43
|
-
::ActionSubscriber::Babou.start_subscribers
|
44
|
-
else
|
45
|
-
fail "ActionSubscriber.configuration.mode must be 'pop' or 'subscribe'. Currently set to '#{::ActionSubscriber.configuration.mode}'"
|
46
|
-
end
|
38
|
+
::ActionSubscriber::Babou.start_subscribers
|
47
39
|
end
|
48
40
|
end
|
49
41
|
|
@@ -62,15 +54,15 @@ module ActionSubscriber
|
|
62
54
|
end
|
63
55
|
|
64
56
|
trap(:TTIN) {
|
65
|
-
::
|
57
|
+
::Thread.new do
|
58
|
+
::ActionSubscriber.print_subscriptions
|
59
|
+
end
|
66
60
|
}
|
67
61
|
|
68
62
|
trap(:USR2) {
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
Ready Size: #{ ::ActionSubscriber::Threadpool.ready_size }
|
73
|
-
CONFIG
|
63
|
+
::Thread.new do
|
64
|
+
::ActionSubscriber.print_threadpool_stats
|
65
|
+
end.join
|
74
66
|
}
|
75
67
|
|
76
68
|
::ActionSubscriber::CLI.start(ARGV)
|
data/lib/action_subscriber.rb
CHANGED
@@ -5,7 +5,6 @@ if ::RUBY_PLATFORM == "java"
|
|
5
5
|
else
|
6
6
|
require "bunny"
|
7
7
|
end
|
8
|
-
require "lifeguard"
|
9
8
|
require "middleware"
|
10
9
|
require "thread"
|
11
10
|
|
@@ -28,7 +27,6 @@ require "action_subscriber/babou"
|
|
28
27
|
require "action_subscriber/route"
|
29
28
|
require "action_subscriber/route_set"
|
30
29
|
require "action_subscriber/router"
|
31
|
-
require "action_subscriber/threadpool"
|
32
30
|
require "action_subscriber/base"
|
33
31
|
|
34
32
|
module ActionSubscriber
|
@@ -36,21 +34,6 @@ module ActionSubscriber
|
|
36
34
|
# Public Class Methods
|
37
35
|
#
|
38
36
|
|
39
|
-
# Loop over all subscribers and pull messages if there are
|
40
|
-
# any waiting in the queue for us.
|
41
|
-
#
|
42
|
-
def self.auto_pop!
|
43
|
-
return if ::ActionSubscriber::Threadpool.busy?
|
44
|
-
route_set.auto_pop!
|
45
|
-
end
|
46
|
-
|
47
|
-
# Loop over all subscribers and register each as
|
48
|
-
# a subscriber.
|
49
|
-
#
|
50
|
-
def self.auto_subscribe!
|
51
|
-
route_set.auto_subscribe!
|
52
|
-
end
|
53
|
-
|
54
37
|
def self.configure
|
55
38
|
yield(configuration) if block_given?
|
56
39
|
end
|
@@ -66,16 +49,11 @@ module ActionSubscriber
|
|
66
49
|
|
67
50
|
def self.print_subscriptions
|
68
51
|
logger.info configuration.inspect
|
69
|
-
route_set.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
logger.info " -- queue: #{route.queue}"
|
75
|
-
logger.info " -- routing_key: #{route.routing_key}"
|
76
|
-
logger.info " -- threadpool: #{route.threadpool.name}, pool_size: #{route.threadpool.pool_size}"
|
77
|
-
end
|
78
|
-
end
|
52
|
+
route_set.print_subscriptions
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.print_threadpool_stats
|
56
|
+
route_set.print_threadpool_stats
|
79
57
|
end
|
80
58
|
|
81
59
|
def self.setup_default_connection!
|
@@ -86,24 +64,14 @@ module ActionSubscriber
|
|
86
64
|
route_set.setup_subscriptions!
|
87
65
|
end
|
88
66
|
|
89
|
-
def self.
|
90
|
-
|
91
|
-
print_subscriptions
|
92
|
-
end
|
93
|
-
|
94
|
-
def self.start_subscribers
|
95
|
-
setup_subscriptions!
|
96
|
-
auto_subscribe!
|
97
|
-
print_subscriptions
|
67
|
+
def self.start_subscribers!
|
68
|
+
route_set.start_subscribers!
|
98
69
|
end
|
99
70
|
|
100
|
-
def self.stop_subscribers!
|
71
|
+
def self.stop_subscribers!(timeout = nil)
|
72
|
+
timeout ||= ::ActionSubscriber.configuration.seconds_to_wait_for_graceful_shutdown
|
101
73
|
route_set.cancel_consumers!
|
102
|
-
|
103
|
-
|
104
|
-
def self.wait_for_threadpools_to_finish_with_timeout(timeout)
|
105
|
-
puts "waiting for threadpools to empty (maximum wait of #{::ActionSubscriber.configuration.seconds_to_wait_for_graceful_shutdown}sec)"
|
106
|
-
::ActionSubscriber::Threadpool.wait_to_finish_with_timeout(timeout)
|
74
|
+
puts "waiting for threadpools to empty (maximum wait of #{timeout}sec)"
|
107
75
|
route_set.wait_to_finish_with_timeout(timeout)
|
108
76
|
end
|
109
77
|
|
@@ -122,11 +90,4 @@ module ActionSubscriber
|
|
122
90
|
end
|
123
91
|
end
|
124
92
|
private_class_method :route_set
|
125
|
-
|
126
|
-
def self.default_routes
|
127
|
-
::ActionSubscriber::Base.inherited_classes.flat_map do |klass|
|
128
|
-
klass.routes
|
129
|
-
end
|
130
|
-
end
|
131
|
-
private_class_method :default_routes
|
132
93
|
end
|
@@ -3,36 +3,12 @@ module ActionSubscriber
|
|
3
3
|
##
|
4
4
|
# Class Methods
|
5
5
|
#
|
6
|
-
|
7
|
-
def self.auto_pop!
|
8
|
-
@pop_mode = true
|
9
|
-
reload_active_record
|
10
|
-
::ActionSubscriber.setup_default_connection!
|
11
|
-
sleep_time = ::ActionSubscriber.configuration.pop_interval.to_i / 1000.0
|
12
|
-
|
13
|
-
::ActionSubscriber.start_queues
|
14
|
-
logger.info "Action Subscriber is popping messages every #{sleep_time} seconds."
|
15
|
-
|
16
|
-
# How often do we want the timer checking for new pops
|
17
|
-
# since we included an eager popper we decreased the
|
18
|
-
# default check interval to 100m
|
19
|
-
while true
|
20
|
-
::ActionSubscriber.auto_pop! unless shutting_down?
|
21
|
-
sleep sleep_time
|
22
|
-
break if shutting_down?
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.pop?
|
27
|
-
!!@pop_mode
|
28
|
-
end
|
29
|
-
|
30
6
|
def self.start_subscribers
|
31
|
-
@prowl_mode = true
|
32
7
|
reload_active_record
|
33
8
|
::ActionSubscriber.setup_default_connection!
|
34
|
-
|
35
|
-
::ActionSubscriber.
|
9
|
+
::ActionSubscriber.setup_subscriptions!
|
10
|
+
::ActionSubscriber.print_subscriptions
|
11
|
+
::ActionSubscriber.start_subscribers!
|
36
12
|
logger.info "Action Subscriber connected"
|
37
13
|
|
38
14
|
while true
|
@@ -41,10 +17,6 @@ module ActionSubscriber
|
|
41
17
|
end
|
42
18
|
end
|
43
19
|
|
44
|
-
def self.prowl?
|
45
|
-
!!@prowl_mode
|
46
|
-
end
|
47
|
-
|
48
20
|
def self.logger
|
49
21
|
::ActionSubscriber::Logging.logger
|
50
22
|
end
|
@@ -59,21 +31,13 @@ module ActionSubscriber
|
|
59
31
|
!!@shutting_down
|
60
32
|
end
|
61
33
|
|
62
|
-
def self.stop_receving_messages!
|
63
|
-
@shutting_down = true
|
64
|
-
::Thread.new do
|
65
|
-
::ActionSubscriber.stop_subscribers!
|
66
|
-
logger.info "stopped all subscribers"
|
67
|
-
end.join
|
68
|
-
end
|
69
|
-
|
70
34
|
def self.stop_server!
|
71
35
|
# this method is called from within a TRAP context so we can't use the logger
|
72
|
-
|
73
|
-
::ActionSubscriber::Babou.stop_receving_messages!
|
74
|
-
::ActionSubscriber.wait_for_threadpools_to_finish_with_timeout(::ActionSubscriber.configuration.seconds_to_wait_for_graceful_shutdown)
|
75
|
-
puts "Shutting down"
|
36
|
+
@shutting_down = true
|
76
37
|
::Thread.new do
|
38
|
+
puts "Stopping subscribers..."
|
39
|
+
::ActionSubscriber.stop_subscribers!
|
40
|
+
puts "Shutting down"
|
77
41
|
::ActionSubscriber::RabbitConnection.subscriber_disconnect!
|
78
42
|
end.join
|
79
43
|
end
|
@@ -56,76 +56,6 @@ module ActionSubscriber
|
|
56
56
|
env.acknowledge
|
57
57
|
end
|
58
58
|
|
59
|
-
def _at_least_once_filter
|
60
|
-
processed_acknowledgement = false
|
61
|
-
yield
|
62
|
-
processed_acknowledgement = acknowledge
|
63
|
-
rescue => error
|
64
|
-
::ActionSubscriber::MessageRetry.redeliver_message_with_backoff(env)
|
65
|
-
processed_acknowledgement = acknowledge
|
66
|
-
raise error
|
67
|
-
ensure
|
68
|
-
rejected_message = false
|
69
|
-
rejected_message = reject unless processed_acknowledgement
|
70
|
-
|
71
|
-
if !processed_acknowledgement && !rejected_message
|
72
|
-
Process.kill(:TTIN, Process.pid)
|
73
|
-
Process.kill(:USR2, Process.pid)
|
74
|
-
|
75
|
-
$stdout << <<-UNREJECTABLE
|
76
|
-
CANNOT ACKNOWLEDGE OR REJECT THE MESSAGE
|
77
|
-
|
78
|
-
This is a exceptional state for ActionSubscriber to enter and puts the current
|
79
|
-
Process in the position of "I can't get new work from RabbitMQ, but also
|
80
|
-
can't acknowledge or reject the work that I currently have" ... While rare
|
81
|
-
this state can happen.
|
82
|
-
|
83
|
-
Instead of continuing to try to process the message ActionSubscriber is
|
84
|
-
sending a Kill signal to the current running process to gracefully shutdown
|
85
|
-
so that the RabbitMQ server will purge any outstanding acknowledgements. If
|
86
|
-
you are running a process monitoring tool (like Upstart) the Subscriber
|
87
|
-
process will be restarted and be able to take on new work.
|
88
|
-
|
89
|
-
** Running a process monitoring tool like Upstart is recommended for this reason **
|
90
|
-
UNREJECTABLE
|
91
|
-
|
92
|
-
Process.kill(:TERM, Process.pid)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def _at_most_once_filter
|
97
|
-
processed_acknowledgement = false
|
98
|
-
processed_acknowledgement = acknowledge
|
99
|
-
yield
|
100
|
-
ensure
|
101
|
-
rejected_message = false
|
102
|
-
rejected_message = reject unless processed_acknowledgement
|
103
|
-
|
104
|
-
if !processed_acknowledgement && !rejected_message
|
105
|
-
Process.kill(:TTIN, Process.pid)
|
106
|
-
Process.kill(:USR2, Process.pid)
|
107
|
-
|
108
|
-
$stdout << <<-UNREJECTABLE
|
109
|
-
CANNOT ACKNOWLEDGE OR REJECT THE MESSAGE
|
110
|
-
|
111
|
-
This is a exceptional state for ActionSubscriber to enter and puts the current
|
112
|
-
Process in the position of "I can't get new work from RabbitMQ, but also
|
113
|
-
can't acknowledge or reject the work that I currently have" ... While rare
|
114
|
-
this state can happen.
|
115
|
-
|
116
|
-
Instead of continuing to try to process the message ActionSubscriber is
|
117
|
-
sending a Kill signal to the current running process to gracefully shutdown
|
118
|
-
so that the RabbitMQ server will purge any outstanding acknowledgements. If
|
119
|
-
you are running a process monitoring tool (like Upstart) the Subscriber
|
120
|
-
process will be restarted and be able to take on new work.
|
121
|
-
|
122
|
-
** Running a process monitoring tool like Upstart is recommended for this reason **
|
123
|
-
UNREJECTABLE
|
124
|
-
|
125
|
-
Process.kill(:TERM, Process.pid)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
59
|
def reject
|
130
60
|
env.reject
|
131
61
|
end
|
@@ -11,41 +11,51 @@ module ActionSubscriber
|
|
11
11
|
bunny_consumers.each(&:cancel)
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
14
|
+
def print_subscriptions
|
15
|
+
routes.group_by(&:subscriber).each do |subscriber, routes|
|
16
|
+
logger.info subscriber.name
|
17
|
+
routes.each do |route|
|
18
|
+
logger.info " -- method: #{route.action}"
|
19
|
+
logger.info " -- connection: #{route.connection_name}"
|
20
|
+
logger.info " -- concurrency: #{route.concurrency}"
|
21
|
+
logger.info " -- exchange: #{route.exchange}"
|
22
|
+
logger.info " -- queue: #{route.queue}"
|
23
|
+
logger.info " -- routing_key: #{route.routing_key}"
|
24
|
+
logger.info " -- prefetch: #{route.prefetch}"
|
25
|
+
logger.error "WARNING having a prefetch lower than your concurrency will prevent your subscriber from fully utilizing its threadpool" if route.prefetch < route.concurrency
|
26
|
+
end
|
27
|
+
end
|
16
28
|
end
|
17
29
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
times_to_pop.times do
|
30
|
+
def print_threadpool_stats
|
31
|
+
logger.info "*DISCLAIMER* the number of running jobs is just a best guess. We don't have a good way to introspect the bunny threadpools so jobs that are sleeping or waiting on IO won't show up as running"
|
32
|
+
subscriptions.group_by{|subscription| subscription[:route].subscriber}.each do |subscriber, subscriptions|
|
33
|
+
logger.info subscriber.name
|
23
34
|
subscriptions.each do |subscription|
|
24
35
|
route = subscription[:route]
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
:action => route.action,
|
34
|
-
:content_type => properties[:content_type],
|
35
|
-
:delivery_tag => delivery_info.delivery_tag,
|
36
|
-
:exchange => delivery_info.exchange,
|
37
|
-
:headers => properties.headers,
|
38
|
-
:message_id => nil,
|
39
|
-
:routing_key => delivery_info.routing_key,
|
40
|
-
:queue => queue.name,
|
41
|
-
}
|
42
|
-
env = ::ActionSubscriber::Middleware::Env.new(route.subscriber, encoded_payload, properties)
|
43
|
-
enqueue_env(route.threadpool, env)
|
36
|
+
work_pool = subscription[:queue].channel.work_pool
|
37
|
+
running_threads = work_pool.threads.select{|thread| thread.status == "run"}.count
|
38
|
+
routes.each do |route|
|
39
|
+
logger.info " -- method: #{route.action}"
|
40
|
+
logger.info " -- concurrency: #{route.concurrency}"
|
41
|
+
logger.info " -- running jobs: #{running_threads}"
|
42
|
+
logger.info " -- backlog: #{work_pool.backlog}"
|
43
|
+
end
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
def
|
48
|
+
def setup_subscriptions!
|
49
|
+
fail ::RuntimeError, "you cannot setup queues multiple times, this should only happen once at startup" unless subscriptions.empty?
|
50
|
+
routes.each do |route|
|
51
|
+
subscriptions << {
|
52
|
+
:route => route,
|
53
|
+
:queue => setup_queue(route),
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def start_subscribers!
|
49
59
|
subscriptions.each do |subscription|
|
50
60
|
route = subscription[:route]
|
51
61
|
queue = subscription[:queue]
|
@@ -84,20 +94,12 @@ module ActionSubscriber
|
|
84
94
|
|
85
95
|
private
|
86
96
|
|
87
|
-
def
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def run_env(env)
|
97
|
-
logger.info "RECEIVED #{env.message_id} from #{env.queue}"
|
98
|
-
::ActiveSupport::Notifications.instrument "process_event.action_subscriber", :subscriber => env.subscriber.to_s, :routing_key => env.routing_key, :queue => env.queue do
|
99
|
-
::ActionSubscriber.config.middleware.call(env)
|
100
|
-
end
|
97
|
+
def setup_queue(route)
|
98
|
+
channel = ::ActionSubscriber::RabbitConnection.with_connection(route.connection_name){ |connection| connection.create_channel(nil, route.concurrency) }
|
99
|
+
exchange = channel.topic(route.exchange)
|
100
|
+
queue = channel.queue(route.queue, :durable => route.durable)
|
101
|
+
queue.bind(exchange, :routing_key => route.routing_key)
|
102
|
+
queue
|
101
103
|
end
|
102
104
|
end
|
103
105
|
end
|