message-driver 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|