message-driver 0.5.3 → 0.6.0
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 +7 -0
- data/.rubocop.yml +3 -0
- data/.rubocop_todo.yml +8 -8
- data/.travis.yml +29 -7
- data/.yardopts +4 -0
- data/CHANGELOG.md +10 -1
- data/Gemfile +3 -1
- data/LICENSE +21 -0
- data/Rakefile +23 -4
- data/features/.nav +3 -3
- data/features/CHANGELOG.md +1 -0
- data/features/step_definitions/logging_steps.rb +1 -1
- data/features/step_definitions/middleware_steps.rb +1 -1
- data/lib/message_driver/adapters/bunny_adapter.rb +6 -10
- data/lib/message_driver/adapters/in_memory_adapter.rb +8 -2
- data/lib/message_driver/broker.rb +47 -9
- data/lib/message_driver/client.rb +77 -24
- data/lib/message_driver/logging.rb +2 -1
- data/lib/message_driver/version.rb +2 -1
- data/lib/message_driver.rb +7 -2
- data/message-driver.gemspec +2 -2
- data/spec/integration/bunny/amqp_integration_spec.rb +20 -0
- data/spec/integration/bunny/bunny_adapter_spec.rb +5 -18
- data/test_lib/broker_config.rb +1 -0
- metadata +28 -40
- data/LICENSE.txt +0 -22
- data/features/CHANGELOG.md +0 -88
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f4ab79020017c5b2b59cf69e11aac19d8b9d15d8
|
4
|
+
data.tar.gz: 30f1943125aae9641606f66f4c5c29635ce9f048
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a144122993d585b84ba3671f8e9b8fcec7d62ca796810dbc6686acae16bfa48e2210c9a10257a04c1e135e35ca33b2c52ef25e7742c4befee6dc2808bf9e4bb3
|
7
|
+
data.tar.gz: 2c1816479290c629be5af7e55fc47971de09105e7eecd430622768278205e1a21227df113c83797a6feba61583e317377d031c3b8ae6fcb77c5f88078ff8336c
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# This configuration was generated by `rubocop --auto-gen-config`
|
2
|
-
# on 2014-
|
2
|
+
# on 2014-11-12 20:52:38 -0600 using RuboCop version 0.27.1.
|
3
3
|
# The point is for the user to remove these configuration records
|
4
4
|
# one by one as the offenses are removed from the code base.
|
5
5
|
# Note that changes in the inspected code, or installation of new
|
6
6
|
# versions of RuboCop, may require this file to be generated again.
|
7
7
|
|
8
|
+
# Offense count: 8
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Enabled: false
|
11
|
+
|
8
12
|
# Offense count: 2
|
9
13
|
# Configuration parameters: CountComments.
|
10
14
|
Metrics/ClassLength:
|
@@ -14,7 +18,7 @@ Metrics/ClassLength:
|
|
14
18
|
Metrics/CyclomaticComplexity:
|
15
19
|
Enabled: false
|
16
20
|
|
17
|
-
# Offense count:
|
21
|
+
# Offense count: 17
|
18
22
|
# Configuration parameters: CountComments.
|
19
23
|
Metrics/MethodLength:
|
20
24
|
Enabled: false
|
@@ -23,16 +27,12 @@ Metrics/MethodLength:
|
|
23
27
|
Metrics/PerceivedComplexity:
|
24
28
|
Enabled: false
|
25
29
|
|
26
|
-
# Offense count:
|
27
|
-
Style/Documentation:
|
28
|
-
Enabled: false
|
29
|
-
|
30
|
-
# Offense count: 9
|
30
|
+
# Offense count: 10
|
31
31
|
# Configuration parameters: MinBodyLength.
|
32
32
|
Style/GuardClause:
|
33
33
|
Enabled: false
|
34
34
|
|
35
|
-
# Offense count:
|
35
|
+
# Offense count: 1
|
36
36
|
Style/ModuleFunction:
|
37
37
|
Enabled: false
|
38
38
|
|
data/.travis.yml
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
2
|
+
sudo: true
|
3
|
+
before_install: gem install bundler
|
3
4
|
bundler_args: --without tools darwin
|
4
5
|
services:
|
5
6
|
- rabbitmq
|
@@ -7,7 +8,7 @@ before_script:
|
|
7
8
|
- ci/travis_setup
|
8
9
|
script: bundle exec rake ci
|
9
10
|
rvm:
|
10
|
-
- 2.
|
11
|
+
- 2.2
|
11
12
|
- 2.0.0
|
12
13
|
- 1.9.3
|
13
14
|
- jruby-19mode
|
@@ -15,12 +16,33 @@ rvm:
|
|
15
16
|
- rbx-2
|
16
17
|
env:
|
17
18
|
- ADAPTER=in_memory
|
18
|
-
- ADAPTER=bunny:1.
|
19
|
-
- ADAPTER=bunny:
|
20
|
-
- ADAPTER=bunny:1.
|
21
|
-
- ADAPTER=bunny:
|
19
|
+
- ADAPTER=bunny:1.7.0
|
20
|
+
- ADAPTER=bunny:2.0.1
|
21
|
+
- ADAPTER=bunny:2.1.0
|
22
|
+
- ADAPTER=bunny:2.2.0
|
22
23
|
- ADAPTER=stomp
|
23
24
|
matrix:
|
25
|
+
fast_finish: true
|
24
26
|
allow_failures:
|
27
|
+
- rvm: rbx-2
|
25
28
|
- rvm: jruby-19mode
|
26
|
-
|
29
|
+
- rvm: 1.9.2
|
30
|
+
exclude:
|
31
|
+
- rvm: 1.9.2
|
32
|
+
env: ADAPTER=bunny:2.0.1
|
33
|
+
- rvm: 1.9.3
|
34
|
+
env: ADAPTER=bunny:2.0.1
|
35
|
+
- rvm: jruby-19mode
|
36
|
+
env: ADAPTER=bunny:2.0.1
|
37
|
+
- rvm: 1.9.2
|
38
|
+
env: ADAPTER=bunny:2.1.0
|
39
|
+
- rvm: 1.9.3
|
40
|
+
env: ADAPTER=bunny:2.1.0
|
41
|
+
- rvm: jruby-19mode
|
42
|
+
env: ADAPTER=bunny:2.1.0
|
43
|
+
- rvm: 1.9.2
|
44
|
+
env: ADAPTER=bunny:2.2.0
|
45
|
+
- rvm: 1.9.3
|
46
|
+
env: ADAPTER=bunny:2.2.0
|
47
|
+
- rvm: jruby-19mode
|
48
|
+
env: ADAPTER=bunny:2.2.0
|
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## 0.
|
3
|
+
## 0.6.0 - 2016-01-28
|
4
|
+
|
5
|
+
* official support for bunny 2.x
|
6
|
+
* support ruby 2.3
|
7
|
+
* drop support for bunny < 1.7
|
8
|
+
* improved API documentation (still a WIP)
|
9
|
+
* fix an issue with confirm_and_wait transactions erroring because there
|
10
|
+
was no open channel
|
11
|
+
|
12
|
+
## 0.5.3 - 2014-10-23
|
4
13
|
|
5
14
|
* In bunny adapter, avoid sending a tx_commit if we haven't done anything requiring
|
6
15
|
a commit inside the transaction block.
|
data/Gemfile
CHANGED
@@ -29,6 +29,8 @@ group :tools do
|
|
29
29
|
gem 'launchy'
|
30
30
|
end
|
31
31
|
|
32
|
+
gem 'thread_safe'
|
33
|
+
|
32
34
|
require File.expand_path('../test_lib/broker_config', __FILE__)
|
33
35
|
|
34
36
|
adapter = BrokerConfig.current_adapter.to_s
|
@@ -48,7 +50,7 @@ end
|
|
48
50
|
|
49
51
|
case provider
|
50
52
|
when :rabbitmq
|
51
|
-
gem 'rabbitmq_http_api_client'
|
53
|
+
gem 'rabbitmq_http_api_client'
|
52
54
|
end
|
53
55
|
|
54
56
|
gem 'coveralls', require: false
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013-2015 Matt Campbell
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/Rakefile
CHANGED
@@ -10,7 +10,9 @@ require 'coveralls/rake/task'
|
|
10
10
|
|
11
11
|
begin
|
12
12
|
require 'rubocop/rake_task'
|
13
|
-
RuboCop::RakeTask.new
|
13
|
+
RuboCop::RakeTask.new do |t|
|
14
|
+
t.fail_on_error = false
|
15
|
+
end
|
14
16
|
rescue LoadError
|
15
17
|
puts 'rubocop not present'
|
16
18
|
task 'rubocop'
|
@@ -29,7 +31,7 @@ namespace :spec do
|
|
29
31
|
end
|
30
32
|
|
31
33
|
cucumber_opts = "--format progress --tag @all_adapters,@#{BrokerConfig.current_adapter} --tag ~@wip"
|
32
|
-
cucumber_opts += ' --tag ~@no_ci' if ENV['CI'] == 'true' && ENV['ADAPTER'] && ENV['ADAPTER'].start_with?('bunny')
|
34
|
+
cucumber_opts += ' --tag ~@no_ci' #if ENV['CI'] == 'true' && ENV['ADAPTER'] && ENV['ADAPTER'].start_with?('bunny')
|
33
35
|
Cucumber::Rake::Task.new(:features) do |t|
|
34
36
|
t.cucumber_opts = cucumber_opts
|
35
37
|
end
|
@@ -40,6 +42,23 @@ end
|
|
40
42
|
desc 'run all the specs'
|
41
43
|
task spec: ['rabbitmq:reset_vhost', 'spec:all']
|
42
44
|
|
45
|
+
begin
|
46
|
+
require 'yard'
|
47
|
+
require 'launchy'
|
48
|
+
|
49
|
+
YARD::Rake::YardocTask.new(:docs)
|
50
|
+
namespace :docs do
|
51
|
+
|
52
|
+
desc 'open the documentation for this gem in your browser'
|
53
|
+
task open: [:docs] do
|
54
|
+
Launchy.open("file:///#{File.join(Dir.pwd, 'doc', 'index.html')}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue LoadError
|
58
|
+
puts "couldn't load yard gems, doc tasks not available"
|
59
|
+
task :docs
|
60
|
+
end
|
61
|
+
|
43
62
|
namespace :rabbitmq do
|
44
63
|
desc 'Reset rabbit vhost'
|
45
64
|
task :reset_vhost do
|
@@ -57,7 +76,7 @@ end
|
|
57
76
|
|
58
77
|
Coveralls::RakeTask.new
|
59
78
|
desc 'run with code coverage'
|
60
|
-
task ci: ['spec', '
|
79
|
+
task ci: ['spec', 'coveralls:push']
|
61
80
|
|
62
81
|
namespace :undertest do
|
63
82
|
BrokerConfig.all_adapters.each do |adapter|
|
@@ -68,4 +87,4 @@ namespace :undertest do
|
|
68
87
|
end
|
69
88
|
end
|
70
89
|
|
71
|
-
task default: [:spec
|
90
|
+
task default: [:spec]
|
data/features/.nav
CHANGED
@@ -6,19 +6,19 @@
|
|
6
6
|
- destination_metadata.feature
|
7
7
|
- client_acks.feature
|
8
8
|
- logging.feature
|
9
|
-
- message_consumers (Message Consumers)
|
9
|
+
- message_consumers (Message Consumers):
|
10
10
|
- basics.feature
|
11
11
|
- auto_ack_consumers.feature
|
12
12
|
- manual_ack_consumers.feature
|
13
13
|
- transactional_ack_consumers.feature
|
14
14
|
- prefetch_size.feature
|
15
15
|
- subscribe_with_a_block.feature
|
16
|
-
- middleware
|
16
|
+
- middleware:
|
17
17
|
- middleware_basics.feature
|
18
18
|
- middleware_ordering.feature
|
19
19
|
- middleware_parameters.feature
|
20
20
|
- middleware_with_blocks.feature
|
21
|
-
- amqp_specific_features (AMQP-Specific Features)
|
21
|
+
- amqp_specific_features (AMQP-Specific Features):
|
22
22
|
- declaring_amqp_destinations.feature
|
23
23
|
- binding_amqp_destinations.feature
|
24
24
|
- server_named_desitnations.feature
|
@@ -0,0 +1 @@
|
|
1
|
+
../CHANGELOG.md
|
@@ -4,7 +4,7 @@ LOG_FILE_NAME = 'cucumber_log_file.log'
|
|
4
4
|
|
5
5
|
Given(/^I am logging to a log file(?: at the (#{STRING_OR_SYM}) level)?$/) do |level|
|
6
6
|
step "an empty file named \"#{LOG_FILE_NAME}\""
|
7
|
-
|
7
|
+
cd('.') do
|
8
8
|
@logger = Logger.new(LOG_FILE_NAME)
|
9
9
|
end
|
10
10
|
step "I set the log level to #{level || 'info'}"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Given('I have a middleware class') do |src|
|
2
2
|
write_file('feature_middleware.rb', src)
|
3
|
-
|
3
|
+
cd('.') { load './feature_middleware.rb' }
|
4
4
|
end
|
5
5
|
|
6
6
|
When(/^I append middleware "(.*?)" to (#{STRING_OR_SYM})$/) do |class_name, dest_name|
|
@@ -253,7 +253,7 @@ module MessageDriver
|
|
253
253
|
validate_bunny_version
|
254
254
|
@broker = broker
|
255
255
|
@config = config
|
256
|
-
@ack_key =
|
256
|
+
@ack_key = :manual_ack
|
257
257
|
end
|
258
258
|
|
259
259
|
attr_reader :ack_key
|
@@ -338,7 +338,9 @@ module MessageDriver
|
|
338
338
|
end
|
339
339
|
begin
|
340
340
|
if @in_confirms_transaction
|
341
|
-
|
341
|
+
unless @rollback_only || @channel.nil?
|
342
|
+
@channel.wait_for_confirms
|
343
|
+
end
|
342
344
|
else
|
343
345
|
if is_transactional? && valid? && !@need_channel_reset && @require_commit
|
344
346
|
handle_errors do
|
@@ -358,12 +360,6 @@ module MessageDriver
|
|
358
360
|
end
|
359
361
|
end
|
360
362
|
|
361
|
-
def wait_for_confirms(channel)
|
362
|
-
# FIXME: make the thread-safety of this better once https://github.com/ruby-amqp/bunny/issues/227 is fixed
|
363
|
-
channel.wait_for_confirms until channel.unconfirmed_set.empty?
|
364
|
-
end
|
365
|
-
private :wait_for_confirms
|
366
|
-
|
367
363
|
def rollback_transaction
|
368
364
|
@rollback_only = true
|
369
365
|
commit_transaction
|
@@ -536,10 +532,10 @@ module MessageDriver
|
|
536
532
|
end
|
537
533
|
|
538
534
|
def validate_bunny_version
|
539
|
-
required = Gem::Requirement.create('>= 1.
|
535
|
+
required = Gem::Requirement.create('>= 1.7.0')
|
540
536
|
current = Gem::Version.create(Bunny::VERSION)
|
541
537
|
unless required.satisfied_by? current
|
542
|
-
fail MessageDriver::Error, 'bunny 1.
|
538
|
+
fail MessageDriver::Error, 'bunny 1.7.0 or later is required for the bunny adapter'
|
543
539
|
end
|
544
540
|
end
|
545
541
|
end
|
@@ -81,8 +81,14 @@ module MessageDriver
|
|
81
81
|
def initialize(broker, _config = {})
|
82
82
|
@broker = broker
|
83
83
|
@destinations = {}
|
84
|
-
|
85
|
-
|
84
|
+
begin
|
85
|
+
require 'thread_safe'
|
86
|
+
@message_store = ThreadSafe::Cache.new { |h, k| h[k] = [] }
|
87
|
+
@subscriptions = ThreadSafe::Cache.new { |h, k| h[k] = [] }
|
88
|
+
rescue LoadError
|
89
|
+
@message_store = Hash.new { |h, k| h[k] = [] }
|
90
|
+
@subscriptions = Hash.new { |h, k| h[k] = [] }
|
91
|
+
end
|
86
92
|
end
|
87
93
|
|
88
94
|
def build_context
|
@@ -4,9 +4,18 @@ module MessageDriver
|
|
4
4
|
|
5
5
|
DEFAULT_BROKER_NAME = :default
|
6
6
|
|
7
|
-
attr_reader :adapter
|
7
|
+
attr_reader :adapter
|
8
|
+
attr_reader :configuration
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
# @private
|
12
|
+
attr_reader :destinations, :consumers
|
8
13
|
|
9
14
|
class << self
|
15
|
+
# @overload configure(options)
|
16
|
+
# @overload configure(name, options)
|
17
|
+
# @param name [Symbol] when configuring multiple brokers, this symbol will differentiate between brokers
|
18
|
+
# @param options [Hash] options to be passed to the adapter class
|
10
19
|
def configure(name = DEFAULT_BROKER_NAME, options)
|
11
20
|
if brokers.keys.include? name
|
12
21
|
fail BrokerAlreadyConfigured, "there is already a broker named #{name} configured"
|
@@ -14,10 +23,11 @@ module MessageDriver
|
|
14
23
|
brokers[name] = new(name, options)
|
15
24
|
end
|
16
25
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
# @overload broker
|
27
|
+
# @overload broker(name)
|
28
|
+
# @param name [Symbol] the name of the broker you wish to define
|
29
|
+
# @return [Broker] the specified broker
|
30
|
+
# @raise [BrokerNotConfigured] if a broker by that name has not yet been configured
|
21
31
|
def broker(name = DEFAULT_BROKER_NAME)
|
22
32
|
result = brokers[name]
|
23
33
|
if result.nil?
|
@@ -27,6 +37,17 @@ module MessageDriver
|
|
27
37
|
result
|
28
38
|
end
|
29
39
|
|
40
|
+
# Yields the specified broker so that destinations and consumers can be defined on it.
|
41
|
+
# @overload define
|
42
|
+
# @overload define(name)
|
43
|
+
# @param (see #broker)
|
44
|
+
# @yield [Broker] the specified broker
|
45
|
+
# @raise (see #broker)
|
46
|
+
def define(name = DEFAULT_BROKER_NAME)
|
47
|
+
yield broker(name)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @private
|
30
51
|
def client(name)
|
31
52
|
unless (result = clients[name])
|
32
53
|
result = clients[name] = Client.for_broker(name)
|
@@ -34,24 +55,32 @@ module MessageDriver
|
|
34
55
|
result
|
35
56
|
end
|
36
57
|
|
58
|
+
# stops all the brokers
|
59
|
+
# @see #stop
|
37
60
|
def stop_all
|
38
61
|
each_broker do |brk|
|
39
62
|
brk.stop
|
40
63
|
end
|
41
64
|
end
|
42
65
|
|
66
|
+
# restarts all the brokers
|
67
|
+
# @see #restart
|
43
68
|
def restart_all
|
44
69
|
each_broker do |brk|
|
45
70
|
brk.restart
|
46
71
|
end
|
47
72
|
end
|
48
73
|
|
74
|
+
# Resets all the brokers for testing purposes.
|
75
|
+
# @see Adapter::Base#reset_after_tests
|
49
76
|
def reset_after_tests
|
50
77
|
each_broker do |brk|
|
51
78
|
brk.adapter.reset_after_tests
|
52
79
|
end
|
53
80
|
end
|
54
81
|
|
82
|
+
# Stops and un-configures all the brokers
|
83
|
+
# @see #stop
|
55
84
|
def reset
|
56
85
|
each_broker do |brk|
|
57
86
|
begin
|
@@ -80,6 +109,7 @@ module MessageDriver
|
|
80
109
|
end
|
81
110
|
end
|
82
111
|
|
112
|
+
# @private
|
83
113
|
def initialize(name = DEFAULT_BROKER_NAME, options)
|
84
114
|
@name = name
|
85
115
|
@adapter = resolve_adapter(options[:adapter], options)
|
@@ -90,27 +120,31 @@ module MessageDriver
|
|
90
120
|
logger.debug 'MessageDriver configured successfully!'
|
91
121
|
end
|
92
122
|
|
93
|
-
|
94
|
-
MessageDriver.logger
|
95
|
-
end
|
96
|
-
|
123
|
+
# @return [MessageDriver::Client] the client module for this broker
|
97
124
|
def client
|
98
125
|
@client ||= self.class.client(name)
|
99
126
|
end
|
100
127
|
|
128
|
+
# stops the adapter for this Broker
|
129
|
+
# @see Adapters::Base#stop
|
101
130
|
def stop
|
102
131
|
@adapter.stop
|
103
132
|
@stopped = true
|
104
133
|
end
|
105
134
|
|
135
|
+
# @return [Boolean] true if the broker is currently stopped
|
106
136
|
def stopped?
|
107
137
|
@stopped
|
108
138
|
end
|
109
139
|
|
140
|
+
# Restarts the Broker, stopping it first if needed. This results in a new
|
141
|
+
# adapter instance being constructed.
|
142
|
+
# @return [Adapter::Base] the newly constructed adapter
|
110
143
|
def restart
|
111
144
|
@adapter.stop unless stopped?
|
112
145
|
@adapter = resolve_adapter(@configuration[:adapter], @configuration)
|
113
146
|
@stopped = false
|
147
|
+
@adapter
|
114
148
|
end
|
115
149
|
|
116
150
|
def dynamic_destination(dest_name, dest_options = {}, message_props = {})
|
@@ -127,6 +161,10 @@ module MessageDriver
|
|
127
161
|
@consumers[key] = block
|
128
162
|
end
|
129
163
|
|
164
|
+
# Find a previously declared Destination
|
165
|
+
# @param destination_name [Symbol] the name of the destination
|
166
|
+
# @return [Destination::Base] the requested destination
|
167
|
+
# @raise [MessageDriver::NoSuchDestinationError] if there is no destination with that name
|
130
168
|
def find_destination(destination_name)
|
131
169
|
destination = @destinations[destination_name]
|
132
170
|
if destination.nil?
|
@@ -1,30 +1,72 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
module MessageDriver
|
4
|
+
# The client module is the primary client API for MessageDriver. It can either be
|
5
|
+
# included in a class that is using it, or used directly.
|
6
|
+
#
|
7
|
+
# @example Included as a Module
|
8
|
+
# class MyClass
|
9
|
+
# include MessageDriver::Client
|
10
|
+
#
|
11
|
+
# def do_work
|
12
|
+
# publish(:my_destination, 'Hi Mom!')
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# @example Used Directly
|
17
|
+
# class DirectClass
|
18
|
+
# def use_directly
|
19
|
+
# MesageDriver::Client.find_destination(:my_queue)
|
20
|
+
# end
|
21
|
+
# end
|
4
22
|
module Client
|
5
23
|
include Logging
|
6
24
|
extend self
|
7
25
|
|
8
|
-
|
9
|
-
|
26
|
+
# @!group Defining and Looking up Destinations
|
27
|
+
|
28
|
+
def dynamic_destination(dest_name, dest_options = {}, message_props = {})
|
29
|
+
current_adapter_context.create_destination(dest_name, dest_options, message_props)
|
10
30
|
end
|
11
31
|
|
12
|
-
|
13
|
-
|
32
|
+
# (see MessageDriver::Broker#find_destination)
|
33
|
+
# @note if +destination_name+ is a {Destination::Base}, +find_destination+ will just
|
34
|
+
# return that destination back
|
35
|
+
def find_destination(destination_name)
|
36
|
+
case destination_name
|
37
|
+
when Destination::Base
|
38
|
+
destination_name
|
39
|
+
else
|
40
|
+
broker.find_destination(destination_name)
|
41
|
+
end
|
14
42
|
end
|
15
43
|
|
16
|
-
|
17
|
-
|
18
|
-
|
44
|
+
# @!endgroup
|
45
|
+
|
46
|
+
# @!group Defining and Looking Up Consumers
|
47
|
+
|
48
|
+
def consumer(key, &block)
|
49
|
+
broker.consumer(key, &block)
|
19
50
|
end
|
20
51
|
|
21
|
-
def
|
22
|
-
|
23
|
-
current_adapter_context.subscribe(destination, options, &consumer)
|
52
|
+
def find_consumer(consumer)
|
53
|
+
broker.find_consumer(consumer)
|
24
54
|
end
|
25
55
|
|
26
|
-
|
27
|
-
|
56
|
+
# @!endgroup
|
57
|
+
|
58
|
+
# @!group Sending Messages
|
59
|
+
|
60
|
+
def publish(destination, body, headers = {}, properties = {})
|
61
|
+
find_destination(destination).publish(body, headers, properties)
|
62
|
+
end
|
63
|
+
|
64
|
+
# @!endgroup
|
65
|
+
|
66
|
+
# @!group Receiving Messages
|
67
|
+
|
68
|
+
def pop_message(destination, options = {})
|
69
|
+
find_destination(destination).pop_message(options)
|
28
70
|
end
|
29
71
|
|
30
72
|
def ack_message(message, options = {})
|
@@ -35,22 +77,19 @@ module MessageDriver
|
|
35
77
|
message.nack(options)
|
36
78
|
end
|
37
79
|
|
38
|
-
def
|
39
|
-
|
80
|
+
def subscribe(destination_name, consumer_name, options = {})
|
81
|
+
consumer = find_consumer(consumer_name)
|
82
|
+
subscribe_with(destination_name, options, &consumer)
|
40
83
|
end
|
41
84
|
|
42
|
-
def
|
43
|
-
|
44
|
-
|
45
|
-
destination
|
46
|
-
else
|
47
|
-
broker.find_destination(destination)
|
48
|
-
end
|
85
|
+
def subscribe_with(destination_name, options = {}, &consumer)
|
86
|
+
destination = find_destination(destination_name)
|
87
|
+
current_adapter_context.subscribe(destination, options, &consumer)
|
49
88
|
end
|
50
89
|
|
51
|
-
|
52
|
-
|
53
|
-
|
90
|
+
# @!endgroup
|
91
|
+
|
92
|
+
# @!group Transaction Management
|
54
93
|
|
55
94
|
def with_message_transaction(options = {})
|
56
95
|
wrapper = fetch_context_wrapper
|
@@ -82,11 +121,15 @@ module MessageDriver
|
|
82
121
|
end
|
83
122
|
end
|
84
123
|
|
124
|
+
# @!endgroup
|
125
|
+
|
126
|
+
# @private
|
85
127
|
def current_adapter_context(initialize = true)
|
86
128
|
ctx = fetch_context_wrapper(initialize)
|
87
129
|
ctx.nil? ? nil : ctx.ctx
|
88
130
|
end
|
89
131
|
|
132
|
+
# @private
|
90
133
|
def with_adapter_context(adapter_context)
|
91
134
|
old_ctx = fetch_context_wrapper(false)
|
92
135
|
Thread.current[adapter_context_key] = build_context_wrapper(adapter_context)
|
@@ -97,6 +140,7 @@ module MessageDriver
|
|
97
140
|
end
|
98
141
|
end
|
99
142
|
|
143
|
+
# @private
|
100
144
|
def clear_context
|
101
145
|
wrapper = fetch_context_wrapper(false)
|
102
146
|
unless wrapper.nil?
|
@@ -105,14 +149,17 @@ module MessageDriver
|
|
105
149
|
end
|
106
150
|
end
|
107
151
|
|
152
|
+
# @return [Broker] the broker associated with this Client module
|
108
153
|
def broker
|
109
154
|
Broker.broker(broker_name)
|
110
155
|
end
|
111
156
|
|
157
|
+
# @return [Symbol] the name of the broker associated with this Client module
|
112
158
|
def broker_name
|
113
159
|
Broker::DEFAULT_BROKER_NAME
|
114
160
|
end
|
115
161
|
|
162
|
+
# @private
|
116
163
|
def for_broker(name)
|
117
164
|
Module.new do
|
118
165
|
include Client
|
@@ -125,6 +172,11 @@ module MessageDriver
|
|
125
172
|
end
|
126
173
|
module_function :for_broker
|
127
174
|
|
175
|
+
# @return [Client] the client for the specified broker
|
176
|
+
# @example
|
177
|
+
# class MyClass
|
178
|
+
# include MessageDriver::Client[:my_broker]
|
179
|
+
# end
|
128
180
|
def [](index)
|
129
181
|
Broker.client(index)
|
130
182
|
end
|
@@ -160,6 +212,7 @@ module MessageDriver
|
|
160
212
|
@__adapter_context_key ||= "#{broker_name}_adapter_context".to_sym
|
161
213
|
end
|
162
214
|
|
215
|
+
# @private
|
163
216
|
class ContextWrapper
|
164
217
|
extend Forwardable
|
165
218
|
|
data/lib/message_driver.rb
CHANGED
@@ -11,13 +11,18 @@ require 'message_driver/subscription'
|
|
11
11
|
require 'message_driver/adapters/base'
|
12
12
|
require 'message_driver/client'
|
13
13
|
|
14
|
+
# Easy message queues for ruby
|
14
15
|
module MessageDriver
|
15
16
|
module_function
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
# (see MessageDriver::Broker.configure)
|
19
|
+
def configure(name = Broker::DEFAULT_BROKER_NAME, options)
|
20
|
+
Broker.configure(name, options)
|
19
21
|
end
|
20
22
|
|
23
|
+
# @!attribute [rw] logger
|
24
|
+
# defaults to an +INFO+ level logger that logs to +STDOUT+
|
25
|
+
# @return [Logger] the logger +MessageDriver+ will use for logging.
|
21
26
|
def logger
|
22
27
|
@__logger ||= Logger.new(STDOUT).tap { |l| l.level = Logger::INFO }
|
23
28
|
end
|
data/message-driver.gemspec
CHANGED
@@ -22,6 +22,6 @@ Gem::Specification.new do |gem|
|
|
22
22
|
|
23
23
|
gem.add_development_dependency 'rake'
|
24
24
|
gem.add_development_dependency 'rspec', '~> 3.1.0'
|
25
|
-
gem.add_development_dependency 'cucumber'
|
26
|
-
gem.add_development_dependency 'aruba'
|
25
|
+
gem.add_development_dependency 'cucumber', '< 2'
|
26
|
+
gem.add_development_dependency 'aruba', '< 0.9'
|
27
27
|
end
|
@@ -78,4 +78,24 @@ RSpec.describe 'AMQP Integration', :bunny, type: :integration do
|
|
78
78
|
expect(msg.body).to eq('Test Message 2')
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
context 'when nothing is done during a transaction' do
|
83
|
+
it 'does not raise an error' do
|
84
|
+
expect do
|
85
|
+
MessageDriver::Client.with_message_transaction do
|
86
|
+
#do nothing
|
87
|
+
end
|
88
|
+
end.not_to raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'with a wait and confirm transaction' do
|
92
|
+
it 'does not raise an error' do
|
93
|
+
expect do
|
94
|
+
MessageDriver::Client.with_message_transaction(type: :confirm_and_wait) do
|
95
|
+
#do nothing
|
96
|
+
end
|
97
|
+
end.not_to raise_error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
81
101
|
end
|
@@ -15,7 +15,7 @@ module MessageDriver
|
|
15
15
|
stub_const('Bunny::VERSION', version)
|
16
16
|
expect do
|
17
17
|
described_class.new(broker, valid_connection_attrs)
|
18
|
-
end.to raise_error MessageDriver::Error, 'bunny 1.
|
18
|
+
end.to raise_error MessageDriver::Error, 'bunny 1.7.0 or later is required for the bunny adapter'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
shared_examples "doesn't raise an error" do
|
@@ -27,13 +27,13 @@ module MessageDriver
|
|
27
27
|
end.to_not raise_error
|
28
28
|
end
|
29
29
|
end
|
30
|
-
%w(0.8.0
|
30
|
+
%w(0.8.0 0.9.0 0.9.8 0.10.7 1.0.3 1.1.2 1.2.1 1.2.2 1.3.0 1.4.1 1.6.2).each do |v|
|
31
31
|
context "bunny version #{v}" do
|
32
32
|
let(:version) { v }
|
33
33
|
include_examples 'raises an error'
|
34
34
|
end
|
35
35
|
end
|
36
|
-
%w(1.
|
36
|
+
%w(1.7.0 1.7.1 2.0.1 2.1.0).each do |v|
|
37
37
|
context "bunny version #{v}" do
|
38
38
|
let(:version) { v }
|
39
39
|
include_examples "doesn't raise an error"
|
@@ -82,21 +82,8 @@ module MessageDriver
|
|
82
82
|
describe '#ack_key' do
|
83
83
|
include_context 'a connected bunny adapter'
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
stub_const('Bunny::VERSION', '1.5.0')
|
88
|
-
end
|
89
|
-
it 'should be :manual_ack' do
|
90
|
-
expect(adapter.ack_key).to eq(:manual_ack)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
context 'when bunny version earlier than 1.5.0' do
|
94
|
-
before do
|
95
|
-
stub_const('Bunny::VERSION', '1.4.1')
|
96
|
-
end
|
97
|
-
it 'should be :manual_ack' do
|
98
|
-
expect(adapter.ack_key).to eq(:ack)
|
99
|
-
end
|
85
|
+
it 'should be :manual_ack' do
|
86
|
+
expect(adapter.ack_key).to eq(:manual_ack)
|
100
87
|
end
|
101
88
|
end
|
102
89
|
|
data/test_lib/broker_config.rb
CHANGED
metadata
CHANGED
@@ -1,80 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: message-driver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.6.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Matt Campbell
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2016-01-28 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 3.1.0
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 3.1.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: cucumber
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - "<"
|
52
46
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
47
|
+
version: '2'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - "<"
|
60
53
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
54
|
+
version: '2'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: aruba
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - "<"
|
68
60
|
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
61
|
+
version: '0.9'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - "<"
|
76
67
|
- !ruby/object:Gem::Version
|
77
|
-
version: '0'
|
68
|
+
version: '0.9'
|
78
69
|
description: Easy message queues for ruby using AMQ, STOMP and others
|
79
70
|
email:
|
80
71
|
- message-driver@soupmatt.com
|
@@ -82,17 +73,18 @@ executables: []
|
|
82
73
|
extensions: []
|
83
74
|
extra_rdoc_files: []
|
84
75
|
files:
|
85
|
-
- .coveralls.yml
|
86
|
-
- .gitignore
|
87
|
-
- .relish
|
88
|
-
- .rspec
|
89
|
-
- .rubocop.yml
|
90
|
-
- .rubocop_todo.yml
|
91
|
-
- .travis.yml
|
76
|
+
- ".coveralls.yml"
|
77
|
+
- ".gitignore"
|
78
|
+
- ".relish"
|
79
|
+
- ".rspec"
|
80
|
+
- ".rubocop.yml"
|
81
|
+
- ".rubocop_todo.yml"
|
82
|
+
- ".travis.yml"
|
83
|
+
- ".yardopts"
|
92
84
|
- CHANGELOG.md
|
93
85
|
- Gemfile
|
94
86
|
- Guardfile
|
95
|
-
- LICENSE
|
87
|
+
- LICENSE
|
96
88
|
- README.md
|
97
89
|
- Rakefile
|
98
90
|
- ci/reset_vhost
|
@@ -197,30 +189,26 @@ files:
|
|
197
189
|
homepage: https://github.com/message-driver/message-driver
|
198
190
|
licenses:
|
199
191
|
- MIT
|
192
|
+
metadata: {}
|
200
193
|
post_install_message:
|
201
194
|
rdoc_options: []
|
202
195
|
require_paths:
|
203
196
|
- lib
|
204
197
|
required_ruby_version: !ruby/object:Gem::Requirement
|
205
|
-
none: false
|
206
198
|
requirements:
|
207
|
-
- -
|
199
|
+
- - ">="
|
208
200
|
- !ruby/object:Gem::Version
|
209
201
|
version: 1.9.2
|
210
202
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
-
none: false
|
212
203
|
requirements:
|
213
|
-
- -
|
204
|
+
- - ">="
|
214
205
|
- !ruby/object:Gem::Version
|
215
206
|
version: '0'
|
216
|
-
segments:
|
217
|
-
- 0
|
218
|
-
hash: -4081124424208803284
|
219
207
|
requirements: []
|
220
208
|
rubyforge_project:
|
221
|
-
rubygems_version:
|
209
|
+
rubygems_version: 2.5.1
|
222
210
|
signing_key:
|
223
|
-
specification_version:
|
211
|
+
specification_version: 4
|
224
212
|
summary: Easy message queues for ruby
|
225
213
|
test_files:
|
226
214
|
- features/.nav
|
data/LICENSE.txt
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
Copyright (c) 2013 Matt Campbell
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/features/CHANGELOG.md
DELETED
@@ -1,88 +0,0 @@
|
|
1
|
-
# Changelog
|
2
|
-
|
3
|
-
## 0.5.3 = 2014-10-23
|
4
|
-
|
5
|
-
* In bunny adapter, avoid sending a tx_commit if we haven't done anything requiring
|
6
|
-
a commit inside the transaction block.
|
7
|
-
|
8
|
-
## 0.5.2 - 2014-10-14
|
9
|
-
|
10
|
-
* fix deprecation warning with bunny 1.5.0
|
11
|
-
|
12
|
-
## 0.5.1 - 2014-10-08
|
13
|
-
|
14
|
-
* put version constant under correct module
|
15
|
-
|
16
|
-
## 0.5.0 - 2014-09-17
|
17
|
-
|
18
|
-
* add support for checking consumer counts on a queue in bunny and in_memory adapters
|
19
|
-
* in_memory adapter now supports multiple subscribers per queue, and does a round-robin
|
20
|
-
through them when sending messages to consumers
|
21
|
-
* upgrade to rspec 3
|
22
|
-
* Middleware can now be used to automatically pre/post-process messages as they are published to
|
23
|
-
or consumed from a destination
|
24
|
-
|
25
|
-
## 0.4.0 - 2014-07-03
|
26
|
-
|
27
|
-
* require bunny 1.2.2 or later
|
28
|
-
* add support for publish confirmations
|
29
|
-
|
30
|
-
## 0.3.0 - 2014-02-26
|
31
|
-
|
32
|
-
* Support for handling multiple broker connections
|
33
|
-
* require bunny 1.1.3 or later
|
34
|
-
* make bunny connections as lazily initialized as possible
|
35
|
-
* bunny transactions start lazily
|
36
|
-
|
37
|
-
## 0.2.2 - 2014-02-21
|
38
|
-
|
39
|
-
* Lots of work on reconnection handling for bunny. Still a work in
|
40
|
-
progress.
|
41
|
-
|
42
|
-
## 0.2.1 - 2013-11-13
|
43
|
-
|
44
|
-
* Correct an issue in handling Bunny::ConnectionLevelErrors.
|
45
|
-
Bunny::Session will now get properly restarted.
|
46
|
-
|
47
|
-
## 0.2.0 - 2013-11-05
|
48
|
-
|
49
|
-
* drop support for bunny 0.9.x
|
50
|
-
* add support for bunny 1.0.x
|
51
|
-
* ability to create subscriptions from a block instead of having to
|
52
|
-
register a consumer
|
53
|
-
|
54
|
-
## 0.2.0.rc2 - 2013-10-30
|
55
|
-
|
56
|
-
* Features
|
57
|
-
* Prefetch size for bunny consumers
|
58
|
-
* Bugs
|
59
|
-
* better error handling for transaction bunny consumers
|
60
|
-
|
61
|
-
## 0.2.0.rc1 - 2013-09-23
|
62
|
-
|
63
|
-
* Features
|
64
|
-
* Message Consumers, all different flavors
|
65
|
-
* Bunny and InMemory adapters
|
66
|
-
* Client Acks
|
67
|
-
* Bunny adapter
|
68
|
-
* Bunny adapter
|
69
|
-
* much better connection and channel error handling, including
|
70
|
-
reconnecting when broker becomes unreachable
|
71
|
-
* Adapters
|
72
|
-
* begin work on Stomp 1.1/1.2 adapter
|
73
|
-
|
74
|
-
## 0.1.0 - 2013-04-05
|
75
|
-
|
76
|
-
Initial Release
|
77
|
-
|
78
|
-
* Features
|
79
|
-
* Publish a message
|
80
|
-
* Broker transactions for publishing
|
81
|
-
* Pop a message
|
82
|
-
* named and dynamic destinations
|
83
|
-
* message_count for destinations
|
84
|
-
* Adapters
|
85
|
-
* InMemory
|
86
|
-
* #reset_after_test method for clearing out queues
|
87
|
-
* Bunny (amqp 0.9)
|
88
|
-
* handle connection and channel errors transparently
|