msgr 1.2.0 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +8 -0
- data/.github/workflows/test.yml +79 -0
- data/.rubocop.yml +12 -47
- data/Appraisals +23 -0
- data/CHANGELOG.md +87 -5
- data/Gemfile +9 -15
- data/README.md +11 -28
- data/Rakefile +10 -6
- data/bin/msgr +1 -0
- data/gemfiles/rails_5.2.gemfile +15 -0
- data/gemfiles/rails_6.0.gemfile +15 -0
- data/gemfiles/rails_6.1.gemfile +15 -0
- data/gemfiles/rails_7.0.gemfile +15 -0
- data/gemfiles/rails_head.gemfile +15 -0
- data/lib/msgr/binding.rb +13 -8
- data/lib/msgr/channel.rb +7 -10
- data/lib/msgr/cli.rb +26 -20
- data/lib/msgr/client.rb +27 -25
- data/lib/msgr/connection.rb +14 -2
- data/lib/msgr/consumer.rb +2 -3
- data/lib/msgr/dispatcher.rb +7 -9
- data/lib/msgr/logging.rb +2 -0
- data/lib/msgr/message.rb +1 -2
- data/lib/msgr/railtie.rb +14 -75
- data/lib/msgr/route.rb +2 -5
- data/lib/msgr/routes.rb +2 -0
- data/lib/msgr/tasks/msgr/drain.rake +11 -0
- data/lib/msgr/test_pool.rb +1 -3
- data/lib/msgr/version.rb +1 -1
- data/lib/msgr.rb +2 -3
- data/msgr.gemspec +8 -6
- data/renovate.json +5 -0
- data/scripts/simple_test.rb +3 -4
- data/spec/fixtures/{msgr-routes-test-1.rb → msgr_routes_test_1.rb} +0 -0
- data/spec/fixtures/msgr_routes_test_drain.rb +5 -0
- data/spec/integration/dummy/Rakefile +1 -1
- data/spec/{msgr/support/.keep → integration/dummy/app/assets/config/manifest.js} +0 -0
- data/spec/integration/dummy/bin/bundle +1 -1
- data/spec/integration/dummy/bin/rails +1 -1
- data/spec/integration/dummy/config/application.rb +1 -1
- data/spec/integration/dummy/config/boot.rb +2 -2
- data/spec/integration/dummy/config/environment.rb +1 -1
- data/spec/integration/dummy/config/rabbitmq.yml +1 -1
- data/spec/integration/msgr/dispatcher_spec.rb +28 -12
- data/spec/integration/msgr/railtie_spec.rb +10 -120
- data/spec/integration/spec_helper.rb +2 -3
- data/spec/integration/{msgr_spec.rb → test_controller_spec.rb} +1 -1
- data/spec/unit/msgr/client_spec.rb +83 -0
- data/spec/{msgr → unit}/msgr/connection_spec.rb +1 -1
- data/spec/{msgr → unit}/msgr/consumer_spec.rb +0 -0
- data/spec/unit/msgr/dispatcher_spec.rb +45 -0
- data/spec/{msgr → unit}/msgr/route_spec.rb +29 -14
- data/spec/{msgr → unit}/msgr/routes_spec.rb +32 -35
- data/spec/{msgr → unit}/msgr_spec.rb +26 -18
- data/spec/{msgr → unit}/spec_helper.rb +1 -1
- data/spec/unit/support/.keep +0 -0
- metadata +43 -36
- data/.travis.yml +0 -43
- data/gemfiles/Gemfile.rails-4-2 +0 -7
- data/gemfiles/Gemfile.rails-5-0 +0 -7
- data/gemfiles/Gemfile.rails-5-1 +0 -7
- data/gemfiles/Gemfile.rails-5-2 +0 -7
- data/gemfiles/Gemfile.rails-master +0 -14
- data/spec/msgr/msgr/client_spec.rb +0 -60
- data/spec/msgr/msgr/dispatcher_spec.rb +0 -44
- data/spec/support/setup.rb +0 -29
data/lib/msgr/channel.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Msgr
|
2
4
|
class Channel
|
3
5
|
include Logging
|
@@ -20,17 +22,17 @@ module Msgr
|
|
20
22
|
@channel.topic(prefix(EXCHANGE_NAME), durable: true).tap do |ex|
|
21
23
|
log(:debug) do
|
22
24
|
"Created exchange #{ex.name} (type: #{ex.type}, " \
|
23
|
-
|
25
|
+
"durable: #{ex.durable?}, auto_delete: #{ex.auto_delete?})"
|
24
26
|
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
def queue(name)
|
30
|
-
@channel.queue(prefix(name), durable: true).tap do |queue|
|
31
|
+
def queue(name, **opts)
|
32
|
+
@channel.queue(prefix(name), durable: true, **opts).tap do |queue|
|
31
33
|
log(:debug) do
|
32
34
|
"Create queue #{queue.name} (durable: #{queue.durable?}, " \
|
33
|
-
|
35
|
+
"auto_delete: #{queue.auto_delete?})"
|
34
36
|
end
|
35
37
|
end
|
36
38
|
end
|
@@ -53,13 +55,8 @@ module Msgr
|
|
53
55
|
log(:debug) { "Nacked message: #{delivery_tag}" }
|
54
56
|
end
|
55
57
|
|
56
|
-
def reject(delivery_tag, requeue = true)
|
57
|
-
@channel.reject delivery_tag, requeue
|
58
|
-
log(:debug) { "Rejected message: #{delivery_tag}" }
|
59
|
-
end
|
60
|
-
|
61
58
|
def close
|
62
59
|
@channel.close if @channel.open?
|
63
60
|
end
|
64
61
|
end
|
65
|
-
end
|
62
|
+
end
|
data/lib/msgr/cli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'optionparser'
|
2
4
|
|
3
5
|
module Msgr
|
@@ -8,7 +10,8 @@ module Msgr
|
|
8
10
|
@options = options
|
9
11
|
|
10
12
|
if !File.exist?(options[:require]) ||
|
11
|
-
|
13
|
+
(File.directory?(options[:require]) &&
|
14
|
+
!File.exist?("#{options[:require]}/config/application.rb"))
|
12
15
|
raise <<~ERR
|
13
16
|
Rails application or required ruby file not found: #{options[:require]}
|
14
17
|
ERR
|
@@ -22,15 +25,13 @@ module Msgr
|
|
22
25
|
require 'rails'
|
23
26
|
if ::Rails::VERSION::MAJOR == 4
|
24
27
|
require File.expand_path("#{options[:require]}/config/application.rb")
|
25
|
-
::Rails::Application.initializer
|
28
|
+
::Rails::Application.initializer 'msgr.eager_load' do
|
26
29
|
::Rails.application.config.eager_load = true
|
27
30
|
end
|
28
|
-
require 'msgr/railtie'
|
29
|
-
require File.expand_path("#{options[:require]}/config/environment.rb")
|
30
|
-
else
|
31
|
-
require 'msgr/railtie'
|
32
|
-
require File.expand_path("#{options[:require]}/config/environment.rb")
|
33
31
|
end
|
32
|
+
|
33
|
+
require 'msgr/railtie'
|
34
|
+
require File.expand_path("#{options[:require]}/config/environment.rb")
|
34
35
|
else
|
35
36
|
require(options[:require])
|
36
37
|
end
|
@@ -40,17 +41,16 @@ module Msgr
|
|
40
41
|
Signal.trap('INT') { w.puts 'INT' }
|
41
42
|
Signal.trap('TERM') { w.puts 'TERM' }
|
42
43
|
|
43
|
-
Msgr.logger = Logger.new(
|
44
|
+
Msgr.logger = Logger.new($stdout)
|
44
45
|
Msgr.client.start
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
47
|
+
# Wait until we receive a signal
|
48
|
+
readable = IO.select([r])
|
49
|
+
case readable.first[0].gets.strip
|
50
|
+
when 'INT', 'TERM' # Safe shutdown
|
51
|
+
Msgr.client.stop
|
52
|
+
else # Error
|
53
|
+
exit 1
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
@@ -61,18 +61,24 @@ module Msgr
|
|
61
61
|
|
62
62
|
private
|
63
63
|
|
64
|
-
def parse(
|
64
|
+
def parse(_argv)
|
65
65
|
options = {
|
66
66
|
require: Dir.pwd,
|
67
|
-
environment: 'development'
|
67
|
+
environment: 'development',
|
68
68
|
}
|
69
69
|
|
70
70
|
OptionParser.new do |o|
|
71
|
-
o.on
|
71
|
+
o.on(
|
72
|
+
'-r', '--require [PATH|DIR]',
|
73
|
+
'Location of Rails application (default to current directory)',
|
74
|
+
) do |arg|
|
72
75
|
options[:require] = arg
|
73
76
|
end
|
74
77
|
|
75
|
-
o.on
|
78
|
+
o.on(
|
79
|
+
'-e', '--environment [env]',
|
80
|
+
'Rails environment (default to development)',
|
81
|
+
) do |arg|
|
76
82
|
options[:environment] = arg
|
77
83
|
end
|
78
84
|
end.parse!
|
data/lib/msgr/client.rb
CHANGED
@@ -2,37 +2,31 @@
|
|
2
2
|
|
3
3
|
require 'uri'
|
4
4
|
require 'cgi'
|
5
|
+
require 'json'
|
5
6
|
|
6
7
|
module Msgr
|
7
|
-
# rubocop:disable Metrics/ClassLength
|
8
8
|
class Client
|
9
9
|
include Logging
|
10
10
|
|
11
11
|
attr_reader :config
|
12
12
|
|
13
|
-
# rubocop:disable MethodLength
|
14
13
|
def initialize(config = {})
|
15
14
|
@config = {
|
16
15
|
host: '127.0.0.1',
|
17
16
|
vhost: '/',
|
18
|
-
max: 2
|
17
|
+
max: 2,
|
19
18
|
}
|
20
19
|
|
21
|
-
@config.merge! parse(config.delete(:uri)) if config
|
20
|
+
@config.merge! parse(config.delete(:uri)) if config[:uri]
|
22
21
|
@config.merge! config.symbolize_keys
|
23
22
|
|
24
23
|
@mutex = ::Mutex.new
|
25
|
-
@routes =
|
24
|
+
@routes = load_routes
|
26
25
|
@pid ||= ::Process.pid
|
27
26
|
|
28
27
|
log(:debug) { "Created new client on process ##{@pid}..." }
|
29
28
|
end
|
30
|
-
# rubocop:enable all
|
31
29
|
|
32
|
-
# rubocop:disable AbcSize
|
33
|
-
# rubocop:disable MethodLength
|
34
|
-
# rubocop:disable PerceivedComplexity
|
35
|
-
# rubocop:disable CyclomaticComplexity
|
36
30
|
def uri
|
37
31
|
@uri = begin
|
38
32
|
uri = ::URI.parse('amqp://localhost')
|
@@ -50,7 +44,6 @@ module Msgr
|
|
50
44
|
uri
|
51
45
|
end
|
52
46
|
end
|
53
|
-
# rubocop:enable all
|
54
47
|
|
55
48
|
def running?
|
56
49
|
mutex.synchronize do
|
@@ -59,7 +52,6 @@ module Msgr
|
|
59
52
|
end
|
60
53
|
end
|
61
54
|
|
62
|
-
# rubocop:disable AbcSize
|
63
55
|
def start
|
64
56
|
mutex.synchronize do
|
65
57
|
check_process!
|
@@ -67,12 +59,9 @@ module Msgr
|
|
67
59
|
|
68
60
|
log(:debug) { "Start on #{uri}..." }
|
69
61
|
|
70
|
-
@routes << config[:routing_file] if config[:routing_file].present?
|
71
|
-
@routes.reload
|
72
62
|
connection.bind(@routes)
|
73
63
|
end
|
74
64
|
end
|
75
|
-
# rubocop:enable all
|
76
65
|
|
77
66
|
def connect
|
78
67
|
mutex.synchronize do
|
@@ -85,7 +74,6 @@ module Msgr
|
|
85
74
|
end
|
86
75
|
end
|
87
76
|
|
88
|
-
# rubocop:disable AbcSize
|
89
77
|
def stop(opts = {})
|
90
78
|
mutex.synchronize do
|
91
79
|
check_process!
|
@@ -100,7 +88,6 @@ module Msgr
|
|
100
88
|
reset
|
101
89
|
end
|
102
90
|
end
|
103
|
-
# rubocop:enable all
|
104
91
|
|
105
92
|
def purge(release: false)
|
106
93
|
mutex.synchronize do
|
@@ -112,6 +99,15 @@ module Msgr
|
|
112
99
|
end
|
113
100
|
end
|
114
101
|
|
102
|
+
##
|
103
|
+
# Purge all queues known to Msgr, if they exist.
|
104
|
+
#
|
105
|
+
def drain
|
106
|
+
@routes.each do |route|
|
107
|
+
connection.purge_queue(route.name)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
115
111
|
def publish(payload, opts = {})
|
116
112
|
mutex.synchronize do
|
117
113
|
check_process!
|
@@ -149,9 +145,10 @@ module Msgr
|
|
149
145
|
|
150
146
|
def check_process!
|
151
147
|
return if ::Process.pid == @pid
|
148
|
+
|
152
149
|
log(:warn) do
|
153
150
|
"Fork detected. Reset internal state. (Old PID: #{@pid} / " \
|
154
|
-
|
151
|
+
"New PID: #{::Process.pid}"
|
155
152
|
end
|
156
153
|
|
157
154
|
reset
|
@@ -178,22 +175,27 @@ module Msgr
|
|
178
175
|
@dispatcher = nil
|
179
176
|
end
|
180
177
|
|
181
|
-
# rubocop:disable AbcSize
|
182
178
|
def parse(uri)
|
183
179
|
# Legacy parsing of URI configuration; does not follow usual
|
184
180
|
# AMQP vhost encoding but used regular URL path
|
185
181
|
uri = ::URI.parse(uri)
|
186
182
|
|
187
183
|
config = {}
|
188
|
-
config[:user]
|
189
|
-
config[:pass]
|
190
|
-
config[:host]
|
191
|
-
config[:port]
|
192
|
-
config[:vhost] ||= uri.path
|
184
|
+
config[:user] ||= uri.user if uri.user
|
185
|
+
config[:pass] ||= uri.password if uri.password
|
186
|
+
config[:host] ||= uri.host if uri.host
|
187
|
+
config[:port] ||= uri.port if uri.port
|
188
|
+
config[:vhost] ||= uri.path unless uri.path.empty?
|
193
189
|
config[:ssl] ||= uri.scheme.casecmp('amqps').zero?
|
194
190
|
|
195
191
|
config
|
196
192
|
end
|
197
|
-
|
193
|
+
|
194
|
+
def load_routes
|
195
|
+
Routes.new.tap do |routes|
|
196
|
+
routes << config[:routing_file] if config[:routing_file].present?
|
197
|
+
routes.reload
|
198
|
+
end
|
199
|
+
end
|
198
200
|
end
|
199
201
|
end
|
data/lib/msgr/connection.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'bunny'
|
4
4
|
|
5
5
|
module Msgr
|
6
|
-
# rubocop:disable Metrics/ClassLength
|
7
6
|
class Connection
|
8
7
|
include Logging
|
9
8
|
|
@@ -49,6 +48,7 @@ module Msgr
|
|
49
48
|
|
50
49
|
def release
|
51
50
|
return if bindings.empty?
|
51
|
+
|
52
52
|
log(:debug) { "Release bindings (#{bindings.size})..." }
|
53
53
|
|
54
54
|
bindings.each(&:release)
|
@@ -56,6 +56,7 @@ module Msgr
|
|
56
56
|
|
57
57
|
def delete
|
58
58
|
return if bindings.empty?
|
59
|
+
|
59
60
|
log(:debug) { "Delete bindings (#{bindings.size})..." }
|
60
61
|
|
61
62
|
bindings.each(&:delete)
|
@@ -63,11 +64,22 @@ module Msgr
|
|
63
64
|
|
64
65
|
def purge(**kwargs)
|
65
66
|
return if bindings.empty?
|
67
|
+
|
66
68
|
log(:debug) { "Purge bindings (#{bindings.size})..." }
|
67
69
|
|
68
70
|
bindings.each {|b| b.purge(**kwargs) }
|
69
71
|
end
|
70
72
|
|
73
|
+
def purge_queue(name)
|
74
|
+
# Creating the queue in passive mode ensures that queues that do not exist
|
75
|
+
# won't be created just to purge them.
|
76
|
+
# That requires creating a new channel every time, as exceptions (on
|
77
|
+
# missing queues) invalidate the channel.
|
78
|
+
channel.queue(name, passive: true).purge
|
79
|
+
rescue Bunny::NotFound
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
71
83
|
def bindings
|
72
84
|
@bindings ||= []
|
73
85
|
end
|
@@ -76,7 +88,7 @@ module Msgr
|
|
76
88
|
if routes.empty?
|
77
89
|
log(:warn) do
|
78
90
|
"No routes to bound to. Bind will have no effect:\n" \
|
79
|
-
|
91
|
+
" #{routes.inspect}"
|
80
92
|
end
|
81
93
|
else
|
82
94
|
bind_all(routes)
|
data/lib/msgr/consumer.rb
CHANGED
@@ -5,6 +5,7 @@ module Msgr
|
|
5
5
|
include Logging
|
6
6
|
|
7
7
|
attr_reader :message
|
8
|
+
|
8
9
|
delegate :payload, to: :@message
|
9
10
|
delegate :action, to: :'@message.route'
|
10
11
|
delegate :consumer, to: :'@message.consumer'
|
@@ -14,9 +15,7 @@ module Msgr
|
|
14
15
|
@auto_ack || @auto_ack.nil?
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
|
-
@auto_ack = val
|
19
|
-
end
|
18
|
+
attr_writer :auto_ack
|
20
19
|
end
|
21
20
|
|
22
21
|
def dispatch(message)
|
data/lib/msgr/dispatcher.rb
CHANGED
@@ -27,9 +27,6 @@ module Msgr
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
# rubocop:disable Metrics/AbcSize
|
31
|
-
# rubocop:disable Metrics/MethodLength
|
32
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
33
30
|
def dispatch(message)
|
34
31
|
consumer_class = Object.const_get message.route.consumer
|
35
32
|
|
@@ -37,17 +34,18 @@ module Msgr
|
|
37
34
|
|
38
35
|
consumer_class.new.dispatch message
|
39
36
|
|
40
|
-
# Acknowledge message
|
41
|
-
|
42
|
-
|
37
|
+
# Acknowledge message only if it is not already acknowledged and auto
|
38
|
+
# acknowledgment is enabled.
|
39
|
+
message.ack unless message.acked? || !consumer_class.auto_ack?
|
40
|
+
rescue StandardError => e
|
43
41
|
message.nack unless message.acked?
|
44
42
|
|
45
43
|
log(:error) do
|
46
|
-
"Dispatcher error: #{
|
47
|
-
|
44
|
+
"Dispatcher error: #{e.class.name}: #{e}\n" +
|
45
|
+
e.backtrace.join("\n")
|
48
46
|
end
|
49
47
|
|
50
|
-
raise
|
48
|
+
raise e if config[:raise_exceptions]
|
51
49
|
ensure
|
52
50
|
if defined?(ActiveRecord) &&
|
53
51
|
ActiveRecord::Base.connection_pool.active_connection?
|
data/lib/msgr/logging.rb
CHANGED
data/lib/msgr/message.rb
CHANGED
@@ -11,8 +11,7 @@ module Msgr
|
|
11
11
|
@payload = payload
|
12
12
|
@route = route
|
13
13
|
|
14
|
-
# rubocop:disable Style/GuardClause
|
15
|
-
if content_type == 'application/json'
|
14
|
+
if content_type == 'application/json' # rubocop:disable Style/GuardClause
|
16
15
|
@payload = JSON.parse(payload)
|
17
16
|
@payload.symbolize_keys! if @payload.respond_to? :symbolize_keys!
|
18
17
|
end
|
data/lib/msgr/railtie.rb
CHANGED
@@ -4,92 +4,31 @@ module Msgr
|
|
4
4
|
class Railtie < ::Rails::Railtie
|
5
5
|
config.msgr = ActiveSupport::OrderedOptions.new
|
6
6
|
|
7
|
-
if File.exist?("#{Rails.root}/app/consumers")
|
8
|
-
config.autoload_paths << File.expand_path("#{Rails.root}/app/consumers")
|
9
|
-
end
|
10
|
-
|
11
7
|
initializer 'msgr.logger' do |app|
|
12
8
|
app.config.msgr.logger ||= Rails.logger
|
13
9
|
end
|
14
10
|
|
15
|
-
# Start msgr
|
16
11
|
initializer 'msgr.start' do
|
17
12
|
config.after_initialize do |app|
|
18
13
|
Msgr.logger = app.config.msgr.logger
|
19
|
-
|
20
|
-
self.class.load app.config.msgr
|
14
|
+
self.class.load(app.config_for(:rabbitmq).symbolize_keys)
|
21
15
|
end
|
22
16
|
end
|
23
17
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
return unless cfg # no config given -> does not load Msgr
|
28
|
-
|
29
|
-
Msgr.config = cfg
|
30
|
-
Msgr.client.connect if cfg[:checkcredentials]
|
31
|
-
Msgr.start if cfg[:autostart]
|
32
|
-
end
|
33
|
-
|
34
|
-
def parse_config(cfg)
|
35
|
-
unless cfg.is_a? Hash
|
36
|
-
Rails.logger.warn '[Msgr] Could not load rabbitmq config: Config must be a Hash'
|
37
|
-
return nil
|
38
|
-
end
|
39
|
-
|
40
|
-
unless cfg[Rails.env].is_a?(Hash)
|
41
|
-
Rails.logger.warn "Could not load rabbitmq config for environment \"#{Rails.env}\": is not a Hash"
|
42
|
-
return nil
|
43
|
-
end
|
44
|
-
|
45
|
-
cfg = HashWithIndifferentAccess.new cfg[Rails.env]
|
46
|
-
unless cfg[:uri]
|
47
|
-
raise ArgumentError.new('Could not load rabbitmq environment config: URI missing.')
|
48
|
-
end
|
49
|
-
|
50
|
-
case cfg[:autostart]
|
51
|
-
when true, 'true', 'enabled'
|
52
|
-
cfg[:autostart] = true
|
53
|
-
when false, 'false', 'disabled', nil
|
54
|
-
cfg[:autostart] = false
|
55
|
-
else
|
56
|
-
raise ArgumentError.new("Invalid value for rabbitmq config autostart: \"#{cfg[:autostart]}\"")
|
57
|
-
end
|
58
|
-
|
59
|
-
case cfg[:checkcredentials]
|
60
|
-
when true, 'true', 'enabled', nil
|
61
|
-
cfg[:checkcredentials] = true
|
62
|
-
when false, 'false', 'disabled'
|
63
|
-
cfg[:checkcredentials] = false
|
64
|
-
else
|
65
|
-
raise ArgumentError.new("Invalid value for rabbitmq config checkcredentials: \"#{cfg[:checkcredentials]}\"")
|
66
|
-
end
|
67
|
-
|
68
|
-
case cfg[:raise_exceptions]
|
69
|
-
when true, 'true', 'enabled'
|
70
|
-
cfg[:raise_exceptions] = true
|
71
|
-
when false, 'false', 'disabled', nil
|
72
|
-
cfg[:raise_exceptions] = false
|
73
|
-
else
|
74
|
-
raise ArgumentError.new("Invalid value for rabbitmq config raise_exceptions: \"#{cfg[:raise_exceptions]}\"")
|
75
|
-
end
|
76
|
-
|
77
|
-
cfg[:routing_file] ||= Rails.root.join('config/msgr.rb').to_s
|
78
|
-
cfg
|
79
|
-
end
|
80
|
-
|
81
|
-
def load_config(options)
|
82
|
-
if options.rabbitmq_config || !Rails.application.respond_to?(:config_for)
|
83
|
-
load_file options.rabbitmq_config || Rails.root.join('config', 'rabbitmq.yml')
|
84
|
-
else
|
85
|
-
conf = Rails.application.config_for :rabbitmq
|
86
|
-
|
87
|
-
{Rails.env.to_s => conf}
|
88
|
-
end
|
89
|
-
end
|
18
|
+
rake_tasks do
|
19
|
+
load File.expand_path('tasks/msgr/drain.rake', __dir__)
|
20
|
+
end
|
90
21
|
|
91
|
-
|
92
|
-
|
22
|
+
class << self
|
23
|
+
def load(config)
|
24
|
+
# Set defaults
|
25
|
+
config.reverse_merge!(
|
26
|
+
checkcredentials: true,
|
27
|
+
routing_file: Rails.root.join('config/msgr.rb').to_s,
|
28
|
+
)
|
29
|
+
|
30
|
+
Msgr.config = config
|
31
|
+
Msgr.client.connect if config.fetch(:checkcredentials)
|
93
32
|
end
|
94
33
|
end
|
95
34
|
end
|
data/lib/msgr/route.rb
CHANGED
@@ -4,10 +4,7 @@ module Msgr
|
|
4
4
|
class Route
|
5
5
|
attr_reader :consumer, :action, :opts
|
6
6
|
|
7
|
-
MATCH_REGEXP =
|
8
|
-
|
9
|
-
# rubocop:disable Metrics/AbcSize
|
10
|
-
# rubocop:disable Metrics/MethodLength
|
7
|
+
MATCH_REGEXP = %r{\A(?<consumer>(?:\w+/)*\w+)#(?<action>\w+)\z}.freeze
|
11
8
|
def initialize(key, opts = {})
|
12
9
|
@opts = opts
|
13
10
|
raise ArgumentError.new 'Missing `to` options.' unless @opts[:to]
|
@@ -19,7 +16,7 @@ module Msgr
|
|
19
16
|
unless result
|
20
17
|
raise ArgumentError.new \
|
21
18
|
"Invalid consumer format: #{opts[:to].strip.to_s.inspect}. " \
|
22
|
-
'Must be `consumer_class#action`.'
|
19
|
+
'Must be `name/space/consumer_class#action`.'
|
23
20
|
end
|
24
21
|
|
25
22
|
@consumer = "#{result[:consumer].camelize}Consumer"
|
data/lib/msgr/routes.rb
CHANGED
data/lib/msgr/test_pool.rb
CHANGED
@@ -31,8 +31,6 @@ module Msgr
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
-
# rubocop:disable Metrics/AbcSize
|
35
|
-
# rubocop:disable Metrics/MethodLength
|
36
34
|
def ns_run(count: 1, timeout: 5)
|
37
35
|
received = 0
|
38
36
|
|
@@ -59,7 +57,7 @@ module Msgr
|
|
59
57
|
|
60
58
|
class << self
|
61
59
|
def new(*args)
|
62
|
-
@instance ||= super(*args)
|
60
|
+
@instance ||= super(*args) # rubocop:disable Naming/MemoizedInstanceVariableName
|
63
61
|
end
|
64
62
|
|
65
63
|
def run(*args)
|
data/lib/msgr/version.rb
CHANGED
data/lib/msgr.rb
CHANGED
@@ -25,7 +25,8 @@ require 'msgr/railtie' if defined? Rails
|
|
25
25
|
|
26
26
|
module Msgr
|
27
27
|
class << self
|
28
|
-
attr_writer :client, :config
|
28
|
+
attr_writer :client, :config, :logger
|
29
|
+
|
29
30
|
delegate :publish, to: :client
|
30
31
|
|
31
32
|
def config
|
@@ -45,8 +46,6 @@ module Msgr
|
|
45
46
|
@logger
|
46
47
|
end
|
47
48
|
|
48
|
-
attr_writer :logger
|
49
|
-
|
50
49
|
def start
|
51
50
|
client.start
|
52
51
|
client
|
data/msgr.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path('
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
5
|
|
6
6
|
require 'msgr/version'
|
@@ -9,23 +9,25 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.name = 'msgr'
|
10
10
|
spec.version = Msgr::VERSION
|
11
11
|
spec.authors = ['Jan Graichen']
|
12
|
-
spec.email = ['
|
12
|
+
spec.email = ['jgraichen@altimos.de']
|
13
13
|
spec.description = 'Msgr: Rails-like Messaging Framework'
|
14
14
|
spec.summary = 'Msgr: Rails-like Messaging Framework'
|
15
15
|
spec.homepage = 'https://github.com/jgraichen/msgr'
|
16
16
|
spec.license = 'MIT'
|
17
17
|
|
18
|
+
spec.metadata = {
|
19
|
+
'rubygems_mfa_required' => 'true',
|
20
|
+
}
|
21
|
+
|
18
22
|
spec.files = `git ls-files -z`.split("\x0")
|
19
23
|
spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
|
20
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
25
|
spec.require_paths = %w[lib]
|
22
26
|
|
27
|
+
spec.required_ruby_version = '>= 2.5'
|
28
|
+
|
23
29
|
spec.add_dependency 'activesupport'
|
24
30
|
spec.add_dependency 'bunny', '>= 1.4', '< 3.0'
|
25
31
|
|
26
32
|
spec.add_development_dependency 'bundler'
|
27
|
-
|
28
|
-
if ENV['TRAVIS_BUILD_NUMBER']
|
29
|
-
spec.version = "#{spec.version}.1.b#{ENV['TRAVIS_BUILD_NUMBER']}"
|
30
|
-
end
|
31
33
|
end
|
data/scripts/simple_test.rb
CHANGED
@@ -19,7 +19,6 @@ class TestConsumer < Msgr::Consumer
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
#
|
23
22
|
class NullPool
|
24
23
|
def initialize(*); end
|
25
24
|
|
@@ -29,7 +28,7 @@ class NullPool
|
|
29
28
|
end
|
30
29
|
|
31
30
|
@client = Msgr::Client.new user: 'guest', password: 'guest',
|
32
|
-
|
31
|
+
max: 4 # , pool_class: 'NullPool'
|
33
32
|
|
34
33
|
@client.routes.configure do
|
35
34
|
route 'abc.#', to: 'test#index'
|
@@ -45,9 +44,9 @@ end
|
|
45
44
|
|
46
45
|
begin
|
47
46
|
sleep
|
48
|
-
rescue Interrupt
|
47
|
+
rescue Interrupt # rubocop:disable Lint/SuppressedException
|
49
48
|
ensure
|
50
49
|
@client.stop timeout: 10, delete: true
|
51
50
|
end
|
52
51
|
|
53
|
-
|
52
|
+
warn "COUNTER: #{@counter}"
|
File without changes
|