action_subscriber 1.0.6 → 1.1.0.pre.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/action_subscriber +74 -0
- data/lib/action_subscriber.rb +1 -0
- data/lib/action_subscriber/babou.rb +89 -0
- data/lib/action_subscriber/configuration.rb +47 -13
- data/lib/action_subscriber/version.rb +1 -1
- data/spec/lib/action_subscriber/configuration_spec.rb +6 -0
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a9cf8f1cf2e4a08761edf0c5afef05aff4a64c2
|
4
|
+
data.tar.gz: 36929284fd076ff6360c4a305888e9e51b51218f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2bf130f70a4e20bfbb084406390a6684a3320904a62d759ed3e0da8f50453a828dc08516e6a26e493856fc6ad13fecc041baf231db9e50c77333b25782f933c6
|
7
|
+
data.tar.gz: 01965874101c457ccdf7d4f81515b5272eb253789bd26fbb7609e72cb1898acb2d7933957980525b2d49df4d8092b1db1cef1ce93acc58db1c14fc2c213d6226
|
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'active_support'
|
4
|
+
require 'active_support/core_ext'
|
5
|
+
require 'thor'
|
6
|
+
|
7
|
+
module ActionSubscriber
|
8
|
+
class CLI < ::Thor
|
9
|
+
class_option :app, :default => "./config/environment.rb"
|
10
|
+
class_option :mode
|
11
|
+
class_option :host
|
12
|
+
class_option :hosts
|
13
|
+
class_option :pop_interval, :type => :numeric, :desc => "how long to wait between asking for messages (in milliseconds)"
|
14
|
+
class_option :port, :type => :numeric
|
15
|
+
class_option :threadpool_size, :type => :numeric
|
16
|
+
class_option :times_to_pop, :type => :numeric, :desc => "how many messages to get from each queue each time we ask rabbit"
|
17
|
+
|
18
|
+
desc "start", "Start the action subscriber subscription server"
|
19
|
+
long_desc <<-BABOUDESC.strip_heredoc
|
20
|
+
Action Subscriber contains a simple subscriber server to manage event subscriptions in a separate process.
|
21
|
+
BABOUDESC
|
22
|
+
|
23
|
+
def start
|
24
|
+
require options[:app]
|
25
|
+
|
26
|
+
$0 = "Action Subscriber server #{object_id}"
|
27
|
+
puts "Loading configuration..."
|
28
|
+
|
29
|
+
::ActionSubscriber::Configuration.configure_from_yaml_and_cli(options)
|
30
|
+
puts "Starting server..."
|
31
|
+
|
32
|
+
case ::ActionSubscriber.configuration.mode
|
33
|
+
when /pop/i then
|
34
|
+
::ActionSubscriber::Babou.auto_pop!
|
35
|
+
when /subscribe/i then
|
36
|
+
::ActionSubscriber::Babou.start_subscribers
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
[:INT, :QUIT, :TERM].each do |signal|
|
42
|
+
trap(signal) do
|
43
|
+
puts "Stopping server..."
|
44
|
+
wait_loops = 0
|
45
|
+
::ActionSubscriber::Babou.stop_server!
|
46
|
+
|
47
|
+
# Going to wait until the thread pool drains or we wait for 1000 seconds
|
48
|
+
# Only waiting for shut down in pop mode
|
49
|
+
if ::ActionSubscriber::Babou.pop?
|
50
|
+
while ::ActionSubscriber::Threadpool.pool.busy_size > 0 && wait_loops < 1000
|
51
|
+
Thread.pass
|
52
|
+
wait_loops = wait_loops + 1
|
53
|
+
sleep 1
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
exit 0
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
trap(:TTIN) {
|
63
|
+
::ActionSubscriber.print_subscriptions
|
64
|
+
}
|
65
|
+
|
66
|
+
trap(:USR2) {
|
67
|
+
puts <<-CONFIG.strip_heredoc
|
68
|
+
Action Subscriber Stats
|
69
|
+
Pool Size: #{ ::ActionSubscriber.config.threadpool_size }
|
70
|
+
Ready Size: #{ ::ActionSubscriber::Threadpool.ready_size }
|
71
|
+
CONFIG
|
72
|
+
}
|
73
|
+
|
74
|
+
::ActionSubscriber::CLI.start(ARGV)
|
data/lib/action_subscriber.rb
CHANGED
@@ -19,6 +19,7 @@ require "action_subscriber/rabbit_connection"
|
|
19
19
|
require "action_subscriber/subscribable"
|
20
20
|
require "action_subscriber/bunny/subscriber"
|
21
21
|
require "action_subscriber/march_hare/subscriber"
|
22
|
+
require "action_subscriber/babou"
|
22
23
|
require "action_subscriber/threadpool"
|
23
24
|
require "action_subscriber/base"
|
24
25
|
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module ActionSubscriber
|
2
|
+
module Babou
|
3
|
+
##
|
4
|
+
# Class Methods
|
5
|
+
#
|
6
|
+
|
7
|
+
def self.auto_pop!
|
8
|
+
@pop_mode = true
|
9
|
+
reload_active_record
|
10
|
+
load_subscribers unless subscribers_loaded?
|
11
|
+
sleep_time = ::ActionSubscriber.configuration.pop_interval.to_i / 1000.0
|
12
|
+
|
13
|
+
::ActionSubscriber.start_queues
|
14
|
+
puts "\nAction Subscriber is popping messages every #{sleep_time} seconds.\n"
|
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 100ms
|
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
|
+
def self.start_subscribers
|
31
|
+
@prowl_mode = true
|
32
|
+
reload_active_record
|
33
|
+
load_subscribers unless subscribers_loaded?
|
34
|
+
|
35
|
+
::ActionSubscriber.start_subscribers
|
36
|
+
puts "\nAction Subscriber connected\n"
|
37
|
+
|
38
|
+
while true
|
39
|
+
sleep 1.0 #just hang around waiting for messages
|
40
|
+
break if shutting_down?
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.prowl?
|
45
|
+
!!@prowl_mode
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.load_subscribers
|
49
|
+
subscription_paths = ["subscriptions", "subscribers"]
|
50
|
+
path_prefixes = ["lib", "app"]
|
51
|
+
cloned_paths = subscription_paths.dup
|
52
|
+
|
53
|
+
path_prefixes.each do |prefix|
|
54
|
+
cloned_paths.each { |path| subscription_paths << "#{prefix}/#{path}" }
|
55
|
+
end
|
56
|
+
|
57
|
+
absolute_subscription_paths = subscription_paths.map{ |path| ::File.expand_path(path) }
|
58
|
+
absolute_subscription_paths.each do |path|
|
59
|
+
if ::File.exists?("#{path}.rb")
|
60
|
+
load("#{path}.rb")
|
61
|
+
end
|
62
|
+
|
63
|
+
if ::File.directory?(path)
|
64
|
+
::Dir[::File.join(path, "**", "*.rb")].sort.each do |file|
|
65
|
+
load file
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.reload_active_record
|
72
|
+
if defined?(::ActiveRecord::Base) && !::ActiveRecord::Base.connected?
|
73
|
+
::ActiveRecord::Base.establish_connection
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.stop_server!
|
78
|
+
@shutting_down = true
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.shutting_down?
|
82
|
+
!!@shutting_down
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.subscribers_loaded?
|
86
|
+
!::ActionSubscriber::Base.inherited_classes.empty?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -5,30 +5,64 @@ module ActionSubscriber
|
|
5
5
|
:default_exchange,
|
6
6
|
:error_handler,
|
7
7
|
:heartbeat,
|
8
|
-
:timeout,
|
9
8
|
:host,
|
10
9
|
:hosts,
|
10
|
+
:mode,
|
11
|
+
:pop_interval,
|
11
12
|
:port,
|
12
13
|
:prefetch,
|
13
|
-
:
|
14
|
-
:
|
14
|
+
:threadpool_size,
|
15
|
+
:timeout,
|
16
|
+
:times_to_pop
|
17
|
+
|
18
|
+
DEFAULTS = {
|
19
|
+
:allow_low_priority_methods => false,
|
20
|
+
:default_exchange => 'events',
|
21
|
+
:heartbeat => 5,
|
22
|
+
:host => 'localhost',
|
23
|
+
:hosts => [],
|
24
|
+
:mode => 'subscribe',
|
25
|
+
:pop_interval => 100, # in milliseconds
|
26
|
+
:port => 5672,
|
27
|
+
:prefetch => 200,
|
28
|
+
:threadpool_size => 8,
|
29
|
+
:timeout => 1,
|
30
|
+
:times_to_pop => 8
|
31
|
+
}
|
32
|
+
|
33
|
+
##
|
34
|
+
# Class Methods
|
35
|
+
#
|
36
|
+
def self.configure_from_yaml_and_cli(cli_options = {})
|
37
|
+
env = ENV["RAILS_ENV"] || ENV["RACK_ENV"] || ENV["APP_ENV"] || "development"
|
38
|
+
|
39
|
+
yaml_config = {}
|
40
|
+
absolute_config_path = ::File.expand_path(::File.join("config", "action_subscriber.yml"))
|
41
|
+
if ::File.exists?(absolute_config_path)
|
42
|
+
yaml_config = ::YAML.load_file(babou_absolute_config_path, :safe => true)[env]
|
43
|
+
end
|
44
|
+
|
45
|
+
::ActionSubscriber::Configuration::DEFAULTS.each_pair do |key, value|
|
46
|
+
setting = cli_options[key] || yaml_config[key.to_s]
|
47
|
+
::ActionSubscriber.config.__send__("#{key}=", setting) if setting
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Instance Methods
|
53
|
+
#
|
15
54
|
|
16
55
|
def initialize
|
17
|
-
self.allow_low_priority_methods = false
|
18
56
|
self.decoder = {
|
19
57
|
'application/json' => lambda { |payload| JSON.parse(payload) },
|
20
58
|
'text/plain' => lambda { |payload| payload.dup }
|
21
59
|
}
|
22
|
-
|
60
|
+
|
23
61
|
self.error_handler = lambda { |error, env_hash| raise }
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
self.port = 5672
|
29
|
-
self.prefetch = 200
|
30
|
-
self.times_to_pop = 8
|
31
|
-
self.threadpool_size = 8
|
62
|
+
|
63
|
+
DEFAULTS.each_pair do |key, value|
|
64
|
+
self.__send__("#{key}=", value)
|
65
|
+
end
|
32
66
|
end
|
33
67
|
|
34
68
|
##
|
@@ -2,9 +2,15 @@ describe ::ActionSubscriber::Configuration do
|
|
2
2
|
describe "default values" do
|
3
3
|
specify { expect(subject.allow_low_priority_methods).to eq(false) }
|
4
4
|
specify { expect(subject.default_exchange).to eq("events") }
|
5
|
+
specify { expect(subject.heartbeat).to eq(5) }
|
5
6
|
specify { expect(subject.host).to eq("localhost") }
|
7
|
+
specify { expect(subject.mode).to eq('subscribe') }
|
8
|
+
specify { expect(subject.pop_interval).to eq(100) }
|
6
9
|
specify { expect(subject.port).to eq(5672) }
|
10
|
+
specify { expect(subject.prefetch).to eq(200) }
|
7
11
|
specify { expect(subject.threadpool_size).to eq(8) }
|
12
|
+
specify { expect(subject.timeout).to eq(1) }
|
13
|
+
specify { expect(subject.times_to_pop).to eq(8) }
|
8
14
|
end
|
9
15
|
|
10
16
|
describe "add_decoder" do
|
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.1.0.pre.rc0
|
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: 2015-09-
|
15
|
+
date: 2015-09-16 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: activesupport
|
@@ -162,7 +162,8 @@ email:
|
|
162
162
|
- brandonsdewitt@gmail.com
|
163
163
|
- quixoten@gmail.com
|
164
164
|
- michael@riesd.com
|
165
|
-
executables:
|
165
|
+
executables:
|
166
|
+
- action_subscriber
|
166
167
|
extensions: []
|
167
168
|
extra_rdoc_files: []
|
168
169
|
files:
|
@@ -175,11 +176,13 @@ files:
|
|
175
176
|
- README.md
|
176
177
|
- Rakefile
|
177
178
|
- action_subscriber.gemspec
|
179
|
+
- bin/action_subscriber
|
178
180
|
- examples/at_least_once.rb
|
179
181
|
- examples/at_most_once.rb
|
180
182
|
- examples/basic_subscriber.rb
|
181
183
|
- examples/message_acknowledgement.rb
|
182
184
|
- lib/action_subscriber.rb
|
185
|
+
- lib/action_subscriber/babou.rb
|
183
186
|
- lib/action_subscriber/base.rb
|
184
187
|
- lib/action_subscriber/bunny/subscriber.rb
|
185
188
|
- lib/action_subscriber/configuration.rb
|
@@ -236,9 +239,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
236
239
|
version: '2.0'
|
237
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
241
|
requirements:
|
239
|
-
- - "
|
242
|
+
- - ">"
|
240
243
|
- !ruby/object:Gem::Version
|
241
|
-
version:
|
244
|
+
version: 1.3.1
|
242
245
|
requirements: []
|
243
246
|
rubyforge_project:
|
244
247
|
rubygems_version: 2.4.8
|