bunny-publisher 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 81976f1ec6350ac4bd2ec4182f0b0c42dcb99705b014228f896f5183bf3e02af
4
- data.tar.gz: 15cc8eef3348d2eff8367aa3f8167a1762e9a94fa56506168f47618ee857e7ed
3
+ metadata.gz: 201692e546c2e4775b7312c3a2bef73caf0ded34abb7bde4f103c9e77500040c
4
+ data.tar.gz: c71d0c82c4ce663253430b8d24b41ec1818460b40d0d3da4d685ebf544bdde2c
5
5
  SHA512:
6
- metadata.gz: d67b3c8e5a609b61450452a8f87aaa281ee458d10f3c5d551e45b8ab5bdf9fb07e75df06525f7df803b88129a5412229a26f485f4f602d71cf309cc737619806
7
- data.tar.gz: 4cdf52e2d3f6a8f99156b0e7359b6a3bf54841ae80ea3cf461c3ab8f1e105a0cc66d0d7e6cc3a0d25812b607dfddb8222b330508c49821866528cc5f589948e3
6
+ metadata.gz: 1e7216b2416c32fb0cb5930faff903d49a287022fc8d60746b978f8bef944ee57ec7117a7a5ea5d3cc89f3cd510cb5e582966723cedc84f480d8c7f1c91368e2
7
+ data.tar.gz: fd85b2a03fe362ff0b1efe7e7229e552fdcab8c4adecf6186668e9fa7fda14accbbc0f355e3885f28f8a467797ea34458ddb194d4be0d8155d98723708aae7ce
@@ -1,9 +1,58 @@
1
- ## Changes Between 0.1.1 and 0.1.2
1
+ # Changelog
2
2
 
3
- Added [test mode](https://github.com/veeqo/bunny-publisher#test-mode)
3
+ All notable changes to this project will be documented in this file.
4
4
 
5
- ## Changes Between 0.1.0 and 0.1.1
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
 
7
- Minor improvements of unrouted message processing at program exit.
7
+ ## [Unreleased](https://github.com/veeqo/bunny-publisher/compare/v0.2.0...HEAD)
8
8
 
9
- ## Original Release: 0.1.0
9
+
10
+ ## [0.2.0](https://github.com/veeqo/bunny-publisher/compare/v0.1.6...v0.2.0) - 2020-11-30
11
+
12
+ ### Changed
13
+ - [#9](https://github.com/veeqo/bunny-publisher/pull/9) Rework callbacks & Mandatory publisher
14
+ - [#10](https://github.com/veeqo/bunny-publisher/pull/10) Improve errors handling for cases when connection can be recovered
15
+
16
+ ## [0.1.6](https://github.com/veeqo/bunny-publisher/compare/v0.1.5...v0.1.6) - 2020-11-24
17
+
18
+ ### Fixed
19
+ - [#8](https://github.com/veeqo/bunny-publisher/pull/8) Fix errors on recovery from connection failures
20
+
21
+
22
+ ## [0.1.5](https://github.com/veeqo/bunny-publisher/compare/v0.1.4...v0.1.5) - 2020-11-04
23
+
24
+ ### Fixed
25
+ - [#7](https://github.com/veeqo/bunny-publisher/pull/7) Enforce single channel for threaded apps
26
+
27
+
28
+ ## [0.1.4](https://github.com/veeqo/bunny-publisher/compare/v0.1.3...v0.1.4) - 2020-11-03
29
+
30
+ ### Changed
31
+ - [#5](https://github.com/veeqo/bunny-publisher/pull/5) Test against ruby 2.7.2
32
+
33
+ ### Fixed
34
+ - [#6](https://github.com/veeqo/bunny-publisher/pull/6) Do not share channels between threads
35
+
36
+
37
+ ## [0.1.3](https://github.com/veeqo/bunny-publisher/compare/v0.1.2...v0.1.3) - 2020-09-18
38
+
39
+ ### Changed
40
+ - [#2](https://github.com/veeqo/bunny-publisher/pull/2) Use appraisal gem to control gem versions of tests matrix
41
+ - [#3](https://github.com/veeqo/bunny-publisher/pull/3) Require ruby 2.5
42
+
43
+ ### Fixed
44
+ - [#4](https://github.com/veeqo/bunny-publisher/pull/4) Fix deprecation warnings of ruby 2.7
45
+
46
+
47
+ ## [0.1.2](https://github.com/veeqo/bunny-publisher/compare/v0.1.1...v0.1.2) - 2020-07-30
48
+
49
+ ### Added
50
+ - [846369a](https://github.com/veeqo/bunny-publisher/commit/846369a76a9ae1c38e0a08844a5c992412eac520) Test mode
51
+
52
+
53
+ ## [0.1.1](https://github.com/veeqo/bunny-publisher/compare/v0.1.0...v0.1.1) - 2020-05-21
54
+
55
+ ### Changed
56
+ - [fec490c](https://github.com/veeqo/bunny-publisher/commit/fec490c91a7db9d053dba9afde0736a4ce2dde71) Imrove unrouted messages processing
57
+
58
+ ## [0.1.0](https://github.com/veeqo/bunny-publisher/releases/tag/v0.1.0) - 2020-05-20
data/README.md CHANGED
@@ -137,6 +137,26 @@ describe SomeServiceThatPublishesToRabbitMQ, '#call' do
137
137
  end
138
138
  ```
139
139
 
140
+ ## Testing
141
+
142
+ Run rabbitmq server (in separate console):
143
+ ```
144
+ docker run --rm -p 5672:5672 -p 15672:15672 rabbitmq:3.8-management-alpine
145
+ ```
146
+
147
+ Run tests with:
148
+
149
+ ```sh
150
+ bundle
151
+ rake
152
+ ```
153
+
154
+ Use [wwtd](https://github.com/grosser/wwtd) to run test matrix:
155
+ ```sh
156
+ gem install wwtd
157
+ wwtd
158
+ ```
159
+
140
160
  ## Contributing
141
161
 
142
162
  Bug reports and pull requests are welcome on GitHub at https://github.com/veeqo/bunny-publisher.
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support'
4
+ require 'active_support/core_ext'
5
+
3
6
  require 'bunny'
4
7
  require 'bunny_publisher/version'
5
8
  require 'bunny_publisher/callbacks'
@@ -30,7 +33,7 @@ module BunnyPublisher
30
33
  include ::BunnyPublisher::Test if config.delete_field(:test)
31
34
  end
32
35
 
33
- @publisher = klass.new(config.to_h)
36
+ @publisher = klass.new(**config.to_h)
34
37
  end
35
38
 
36
39
  def method_missing(method_name, *args)
@@ -41,7 +44,7 @@ module BunnyPublisher
41
44
  end
42
45
  end
43
46
 
44
- def respond_to_missing?(method_name, include_private = false)
47
+ def respond_to_missing?(method_name, *args)
45
48
  publisher.respond_to?(method_name) || super
46
49
  end
47
50
  end
@@ -6,7 +6,13 @@ module BunnyPublisher
6
6
  class Base
7
7
  include Callbacks
8
8
 
9
- define_callbacks :after_publish, :before_publish, :around_publish
9
+ # A list of errors that can be fixed by a connection recovery
10
+ RETRIABLE_ERRORS = [
11
+ Bunny::ConnectionClosedError,
12
+ Bunny::NetworkFailure,
13
+ Bunny::ConnectionLevelException,
14
+ Timeout::Error # can be raised by Bunny::Channel#with_continuation_timeout
15
+ ].freeze
10
16
 
11
17
  attr_reader :connection, :channel, :exchange
12
18
 
@@ -24,14 +30,20 @@ module BunnyPublisher
24
30
  @connection = publish_connection || connection
25
31
  end
26
32
 
27
- def publish(message, options = {})
28
- ensure_connection!
29
-
30
- run_callback(:before_publish, message, options)
31
- result = run_callback(:around_publish, message, options) { exchange.publish(message, options) }
32
- run_callback(:after_publish, message, options)
33
-
34
- result
33
+ def publish(message, message_options = {})
34
+ @mutex.synchronize do
35
+ @message = message
36
+ @message_options = message_options
37
+
38
+ run_callbacks(:publish) do
39
+ with_errors_handling do
40
+ ensure_connection!
41
+ exchange.publish(message, message_options.dup) # Bunny modifies message options
42
+ end
43
+ end
44
+ ensure
45
+ @message = @message_options = nil
46
+ end
35
47
  end
36
48
 
37
49
  def close
@@ -42,17 +54,68 @@ module BunnyPublisher
42
54
 
43
55
  private
44
56
 
57
+ attr_reader :message, :message_options
58
+
59
+ delegate :logger, to: :connection
60
+
45
61
  def ensure_connection!
46
- @mutex.synchronize { connect! unless connected? }
62
+ @connection ||= build_connection
63
+
64
+ connection.start if should_start_connection?
65
+
66
+ wait_until_connection_ready
67
+
68
+ @channel ||= connection.create_channel
69
+ @exchange ||= build_exchange
47
70
  end
48
71
 
49
- def connect!
50
- @connection ||= build_connection
51
- connection.start
72
+ def reset_exchange!
73
+ ensure_connection!
52
74
  @channel = connection.create_channel
53
75
  @exchange = build_exchange
54
76
  end
55
77
 
78
+ def wait_until_connection_ready
79
+ Timeout.timeout(recovery_timeout * 2) do
80
+ loop do
81
+ return if connection_open? || !connection.automatically_recover?
82
+
83
+ sleep 0.01
84
+ end
85
+ end
86
+ rescue Timeout::Error
87
+ # Connection recovery takes too long, let the next interaction fail with error then.
88
+ end
89
+
90
+ def should_start_connection?
91
+ connection.status == :not_connected || # Lazy connection initialization
92
+ connection.closed?
93
+ end
94
+
95
+ def connection_can_recover?
96
+ connection.automatically_recover? && connection.should_retry_recovery?
97
+ end
98
+
99
+ def connection_open?
100
+ # Do not trust Bunny::Session#open? - it uses :connected & :connecting statuses as "open",
101
+ # while connection is not actually ready to work.
102
+ connection.instance_variable_get(:@status_mutex).synchronize do
103
+ connection.status == :open && connection.transport.open?
104
+ end
105
+ end
106
+
107
+ def recovery_timeout
108
+ # 60 seconds is a default heartbeat timeout https://www.rabbitmq.com/heartbeats.html#heartbeats-timeout
109
+ # Recommended timeout is 5-20 https://www.rabbitmq.com/heartbeats.html#false-positives
110
+ heartbeat_timeout = [
111
+ (connection.respond_to?(:heartbeat_timeout) ? connection.heartbeat_timeout : connection.heartbeat) || 60,
112
+ 5
113
+ ].max
114
+
115
+ # Using x2 of heartbeat timeout to get Bunny chance to detect connection failure & try to recover it
116
+ heartbeat_timeout * 2
117
+ end
118
+
56
119
  def build_connection
57
120
  Bunny.new(@options[:amqp] || ENV['RABBITMQ_URL'], @options)
58
121
  end
@@ -63,8 +126,16 @@ module BunnyPublisher
63
126
  channel.exchange(@exchange_name, @exchange_options)
64
127
  end
65
128
 
66
- def connected?
67
- @connection&.connected? && channel
129
+ def with_errors_handling
130
+ yield
131
+ rescue Bunny::ChannelAlreadyClosed
132
+ reset_exchange!
133
+ retry
134
+ rescue *RETRIABLE_ERRORS => e
135
+ raise unless connection_can_recover?
136
+
137
+ logger.warn { e.inspect }
138
+ retry
68
139
  end
69
140
  end
70
141
  end
@@ -1,41 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'active_support'
4
+ require 'active_support/callbacks'
5
+
3
6
  module BunnyPublisher
4
- # Adds support for callbacks (one per event!)
7
+ # Adds support for callbacks
5
8
  module Callbacks
6
- def self.included(klass)
7
- klass.extend ClassMethods
9
+ extend ActiveSupport::Concern
10
+ include ActiveSupport::Callbacks
11
+
12
+ included do
13
+ define_callbacks :publish
8
14
  end
9
15
 
10
16
  module ClassMethods
11
- def define_callbacks(*events)
12
- events.each do |event|
13
- singleton_class.define_method(event) do |method_or_proc|
14
- callbacks[event] = method_or_proc
15
- end
16
- end
17
+ def before_publish(*filters, &blk)
18
+ set_callback(:publish, :before, *filters, &blk)
17
19
  end
18
20
 
19
- def callbacks
20
- @callbacks ||= {}
21
+ def around_publish(*filters, &blk)
22
+ set_callback(:publish, :around, *filters, &blk)
21
23
  end
22
- end
23
24
 
24
- private
25
-
26
- def run_callback(event, *args, &block)
27
- case (callback = callback_for_event(event))
28
- when nil
29
- yield if block_given?
30
- when Symbol
31
- send(callback, self, *args, &block)
32
- when Proc
33
- callback.call(self, *args, &block)
25
+ def after_publish(*filters, &blk)
26
+ set_callback(:publish, :after, *filters, &blk)
34
27
  end
35
28
  end
36
-
37
- def callback_for_event(event)
38
- self.class.callbacks[event]
39
- end
40
29
  end
41
30
  end
@@ -1,5 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BunnyPublisher
4
- class PublishError < StandardError; end
4
+ class ReturnedMessageError < StandardError; end
5
+
6
+ class CannotCreateQueue < ReturnedMessageError
7
+ def to_s
8
+ [
9
+ 'Can not create queue for re-publishing. Set queue_name, routing_key, '\
10
+ 'or override BunnyPublisher::Mandatory#declare_republish_queue',
11
+ super
12
+ ].join(' ')
13
+ end
14
+ end
5
15
  end
@@ -6,23 +6,44 @@ module BunnyPublisher
6
6
  # Creates queue/binding before re-publishing the same message again.
7
7
  # This publisher DUPLICATES the connection for re-publishing messages!
8
8
  module Mandatory
9
- def self.included(klass)
10
- klass.define_callbacks :on_message_return,
11
- :after_republish,
12
- :before_republish,
13
- :around_republish
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ define_callbacks :republish
13
+ end
14
+
15
+ module ClassMethods
16
+ attr_reader :on_message_return_callback
17
+
18
+ def before_republish(*filters, &blk)
19
+ set_callback(:republish, :before, *filters, &blk)
20
+ end
21
+
22
+ def around_republish(*filters, &blk)
23
+ set_callback(:republish, :around, *filters, &blk)
24
+ end
25
+
26
+ def after_republish(*filters, &blk)
27
+ set_callback(:republish, :after, *filters, &blk)
28
+ end
29
+
30
+ def on_message_return(method_or_proc)
31
+ unless method_or_proc.is_a?(Proc) || method_or_proc.is_a?(Symbol)
32
+ raise ArgumentError, "Method or Proc expected, #{method_or_proc.class} given"
33
+ end
34
+
35
+ @on_message_return_callback = method_or_proc
36
+ end
14
37
  end
15
38
 
16
39
  attr_reader :queue_name, :queue_options
17
40
 
18
- def initialize(republish_connection: nil, queue: nil, queue_options: {}, timeout_at_exit: 5, **options)
19
- super(options)
41
+ def initialize(queue: nil, queue_options: {}, timeout_at_exit: 5, **options)
42
+ super(**options)
20
43
 
21
44
  @queue_name = queue
22
45
  @queue_options = queue_options
23
-
24
- @republish_mutex = Mutex.new
25
- @republish_connection = republish_connection
46
+ @returned_messages = ::Queue.new # ruby queue, not Bunny's one
26
47
 
27
48
  at_exit { wait_for_unrouted_messages_processing(timeout: timeout_at_exit) }
28
49
  end
@@ -31,100 +52,100 @@ module BunnyPublisher
31
52
  super(message, options.merge(mandatory: true))
32
53
  end
33
54
 
34
- def close
35
- republish_connection&.close
36
-
37
- super
38
- end
55
+ def declare_republish_queue
56
+ name = queue_name || message_options[:routing_key]
39
57
 
40
- alias stop close
58
+ ensure_can_create_queue!(name)
41
59
 
42
- def declare_republish_queue(return_info, _properties, _message)
43
- republish_channel.queue(queue_name || return_info.routing_key, queue_options)
60
+ channel.queue(name, queue_options)
44
61
  end
45
62
 
46
- def declare_republish_queue_binding(queue, return_info, _properties, _message)
47
- queue.bind(republish_exchange, routing_key: return_info.routing_key)
63
+ def declare_republish_queue_binding(queue)
64
+ routing_key = message_options[:routing_key] || queue_name
65
+
66
+ queue.bind(exchange, routing_key: routing_key)
48
67
  end
49
68
 
50
69
  private
51
70
 
52
- attr_reader :republish_connection, :republish_channel, :republish_exchange
71
+ attr_reader :returned_messages
53
72
 
54
- def connect!
73
+ def ensure_connection!
55
74
  super
56
75
 
57
- # `on_return` is called within a frameset of amqp connection.
58
- # Any interaction within the same connection leads to error. This is why we need extra connection.
59
- # https://github.com/ruby-amqp/bunny/blob/7fb05abf36637557f75a69790be78f9cc1cea807/lib/bunny/session.rb#L683
60
- if callback_for_event(:on_message_return)
61
- exchange.on_return { |*attrs| run_callback(:on_message_return, *attrs) }
62
- else
63
- exchange.on_return { |*attrs| on_message_return(*attrs) }
64
- end
65
- end
66
-
67
- def ensure_republish_connection!
68
- @republish_mutex.synchronize { connect_for_republish! unless connected_for_republish? }
69
- end
70
-
71
- def connected_for_republish?
72
- republish_connection&.connected? && republish_channel
76
+ configure_exchange_to_process_returns unless @on_return_set
73
77
  end
74
78
 
75
- def connect_for_republish!
76
- @republish_connection ||= build_republish_connection
77
- republish_connection.start
78
- @republish_channel = republish_connection.create_channel
79
- @republish_exchange = clone_exchange_for_republish
80
- end
81
-
82
- def build_republish_connection
83
- Bunny.new(connection.instance_variable_get(:'@opts')) # TODO: find more elegant way to "clone" connection
79
+ def reset_exchange!
80
+ super
81
+ configure_exchange_to_process_returns
84
82
  end
85
83
 
86
- def clone_exchange_for_republish
87
- republish_channel.default_exchange if exchange.name == ''
84
+ def configure_exchange_to_process_returns
85
+ case (callback = self.class.on_message_return_callback)
86
+ when nil
87
+ exchange.on_return { |*attrs| on_message_return(*attrs) }
88
+ when Proc
89
+ exchange.on_return { |*attrs| callback.call(*attrs) }
90
+ when Symbol
91
+ exchange.on_return { |*attrs| send(callback, *attrs) }
92
+ end
88
93
 
89
- republish_channel.exchange exchange.name,
90
- exchange.instance_variable_get(:'@options').merge(type: exchange.type)
94
+ @on_return_set = true
91
95
  end
92
96
 
97
+ # `on_return` is called within a frameset of amqp connection.
98
+ # Any interaction within the same connection leads to error.
99
+ # This is why we process the returned message in a separate thread.
100
+ # https://github.com/ruby-amqp/bunny/blob/7fb05abf36637557f75a69790be78f9cc1cea807/lib/bunny/session.rb#L683
93
101
  def on_message_return(return_info, properties, message)
94
- @unrouted_message_processing = true
95
-
96
- ensure_message_is_unrouted!(return_info, properties, message)
102
+ message_options = properties.to_h.merge(routing_key: return_info.routing_key).compact
97
103
 
98
- setup_queue_for_republish(return_info, properties, message)
104
+ if return_info.reply_text == 'NO_ROUTE'
105
+ returned_messages << [message, message_options]
99
106
 
100
- run_callback(:before_republish, return_info, properties, message)
101
- result = run_callback(:around_republish, return_info, properties, message) do
102
- republish_exchange.publish(message, properties.to_h.merge(routing_key: return_info.routing_key))
107
+ Thread.new { process_returned_message }.tap do |thread|
108
+ thread.abort_on_exception = false
109
+ thread.report_on_exception = true
110
+ end
111
+ else
112
+ # Do not raise error here!
113
+ # The best we can do here is to log to STDERR
114
+ warn 'BunnyPublisher::UnsupportedReplyText: '\
115
+ 'Broker has returned the message with reply_text other than NO_ROUTE '\
116
+ "#{[return_info, properties, message]}"
103
117
  end
104
- run_callback(:after_republish, return_info, properties, message)
105
-
106
- result
107
- ensure
108
- @unrouted_message_processing = false
109
118
  end
110
119
 
111
- def setup_queue_for_republish(return_info, properties, message)
112
- ensure_republish_connection!
113
-
114
- queue = declare_republish_queue(return_info, properties, message)
115
-
116
- # default exchange already has bindings with queues
117
- declare_republish_queue_binding(queue, return_info, properties, message) unless republish_exchange.name == ''
118
-
119
- republish_channel.deregister_queue(queue) # we are not going to work with this queue in this channel
120
+ def process_returned_message
121
+ @mutex.synchronize do
122
+ @unrouted_message_processing = true
123
+ @message, @message_options = returned_messages.pop
124
+
125
+ run_callbacks(:republish) do
126
+ with_errors_handling do
127
+ ensure_connection!
128
+ setup_queue_for_republish
129
+ exchange.publish(message, message_options.merge(mandatory: true))
130
+ end
131
+ end
132
+ ensure
133
+ @message = @message_options = nil
134
+ @unrouted_message_processing = false
135
+ end
120
136
  end
121
137
 
122
- def ensure_message_is_unrouted!(return_info, properties, message)
123
- return if return_info.reply_text == 'NO_ROUTE'
138
+ def setup_queue_for_republish
139
+ queue = declare_republish_queue
140
+
141
+ # default exchange already has bindings with queues, but routing key is required
142
+ if exchange.name == ''
143
+ message_options[:routing_key] = queue.name
144
+ else
145
+ declare_republish_queue_binding(queue)
146
+ end
124
147
 
125
- raise BunnyPublisher::PublishError, message: message,
126
- return_info: return_info,
127
- properties: properties
148
+ channel.deregister_queue(queue) # we are not going to work with this queue in this channel
128
149
  end
129
150
 
130
151
  # TODO: introduce more reliable way to wait for handling of unrouted messages at exit
@@ -133,11 +154,18 @@ module BunnyPublisher
133
154
 
134
155
  return unless @unrouted_message_processing
135
156
 
136
- puts("Waiting up to #{timeout} seconds for unrouted messages handling")
157
+ logger.warn { "Waiting up to #{timeout} seconds for unrouted messages handling" }
137
158
 
138
159
  Timeout.timeout(timeout) { sleep 0.01 while @unrouted_message_processing }
139
160
  rescue Timeout::Error
140
- warn('Some unrouted messages are lost on process exit!')
161
+ logger.warn { 'Some unrouted messages are lost on process exit!' }
162
+ end
163
+
164
+ def ensure_can_create_queue!(name)
165
+ return if name.present?
166
+
167
+ raise BunnyPublisher::CannotCreateQueue, message: message,
168
+ message_options: message_options
141
169
  end
142
170
  end
143
171
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BunnyPublisher
4
- VERSION = '0.1.2'
4
+ VERSION = '0.2.0'
5
5
  end
metadata CHANGED
@@ -1,43 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bunny-publisher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Sharshenov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-27 00:00:00.000000000 Z
11
+ date: 2020-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bunny
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '2.10'
33
+ version: '2.17'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
38
  - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '2.10'
40
+ version: '2.17'
41
+ - !ruby/object:Gem::Dependency
42
+ name: appraisal
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 2.3.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 2.3.0
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: bundler
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - ">="
32
60
  - !ruby/object:Gem::Version
33
- version: '0'
61
+ version: '2.0'
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
- version: '0'
68
+ version: '2.0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: pry-byebug
43
71
  requirement: !ruby/object:Gem::Requirement
@@ -66,34 +94,20 @@ dependencies:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
96
  version: '1.13'
69
- - !ruby/object:Gem::Dependency
70
- name: rake
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '3.0'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: '3.0'
97
111
  description: AMQP publisher for RabbitMQ based on Bunny
98
112
  email:
99
113
  - rustam@sharshenov.com
@@ -101,16 +115,9 @@ executables: []
101
115
  extensions: []
102
116
  extra_rdoc_files: []
103
117
  files:
104
- - ".gitignore"
105
- - ".rspec"
106
- - ".rubocop.yml"
107
- - ".travis.yml"
108
118
  - CHANGELOG.md
109
- - Gemfile
110
119
  - LICENSE.txt
111
120
  - README.md
112
- - Rakefile
113
- - bunny-publisher.gemspec
114
121
  - lib/bunny/publisher.rb
115
122
  - lib/bunny_publisher.rb
116
123
  - lib/bunny_publisher/base.rb
@@ -134,14 +141,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
141
  requirements:
135
142
  - - ">="
136
143
  - !ruby/object:Gem::Version
137
- version: '0'
144
+ version: '2.5'
138
145
  required_rubygems_version: !ruby/object:Gem::Requirement
139
146
  requirements:
140
147
  - - ">="
141
148
  - !ruby/object:Gem::Version
142
149
  version: '0'
143
150
  requirements: []
144
- rubygems_version: 3.0.8
151
+ rubygems_version: 3.1.4
145
152
  signing_key:
146
153
  specification_version: 4
147
154
  summary: AMQP publisher for RabbitMQ based on Bunny
data/.gitignore DELETED
@@ -1,14 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /Gemfile.lock
10
- /.ruby-gemset
11
- /.ruby-version
12
-
13
- # rspec failure tracking
14
- .rspec_status
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
@@ -1,16 +0,0 @@
1
- Layout/LineLength:
2
- Max: 120
3
- Exclude:
4
- - "spec/**/*"
5
-
6
- Lint/AmbiguousBlockAssociation:
7
- Exclude:
8
- - "spec/**/*"
9
-
10
- Metrics/BlockLength:
11
- Exclude:
12
- - "spec/**/*"
13
-
14
- Style/EvalWithLocation:
15
- Exclude:
16
- - "spec/**/*"
@@ -1,16 +0,0 @@
1
- ---
2
- dist: xenial
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.5.8
7
- - 2.6.6
8
- - 2.7.1
9
- env:
10
- - BUNNY_VERSION="~> 2.15"
11
- - BUNNY_VERSION="2.10.0"
12
-
13
- before_install: gem install bundler
14
- before_script:
15
- - ".ci/install_rabbitmq"
16
- bundler_args: --jobs 3 --retry 3
data/Gemfile DELETED
@@ -1,10 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source 'https://rubygems.org'
4
-
5
- git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
-
7
- # Specify your gem's dependencies in bunny-publisher.gemspec
8
- gemspec
9
-
10
- gem 'bunny', ENV.fetch('BUNNY_VERSION', '~> 2.15')
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- task default: :spec
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path('lib', __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require 'bunny_publisher/version'
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = 'bunny-publisher'
9
- spec.version = BunnyPublisher::VERSION
10
- spec.authors = ['Rustam Sharshenov']
11
- spec.email = ['rustam@sharshenov.com']
12
-
13
- spec.summary = 'AMQP publisher for RabbitMQ based on Bunny'
14
- spec.description = 'AMQP publisher for RabbitMQ based on Bunny'
15
- spec.homepage = 'https://github.com/veeqo/bunny-publisher'
16
- spec.license = 'MIT'
17
-
18
- if spec.respond_to?(:metadata)
19
- spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['source_code_uri'] = spec.homepage
21
- spec.metadata['changelog_uri'] = 'https://github.com/veeqo/bunny-publisher/blob/master/CHANGELOG.md'
22
- end
23
-
24
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|\.ci)/}) }
26
- end
27
- spec.require_paths = ['lib']
28
-
29
- spec.add_dependency 'bunny', '~> 2.10'
30
-
31
- spec.add_development_dependency 'bundler'
32
- spec.add_development_dependency 'pry-byebug'
33
- spec.add_development_dependency 'rabbitmq_http_api_client', '~> 1.13'
34
- spec.add_development_dependency 'rake'
35
- spec.add_development_dependency 'rspec'
36
- end