ears 0.11.2 → 0.13.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: 288afca56e18d5cd8add5e50155a37d243daf862079893c2e2aa54728b5ce6dc
4
- data.tar.gz: 7e961cf4efaf97fd72c79a8ff8fd49f2536decc6728a1f8d8ddb176b42de5ff3
3
+ metadata.gz: ba8ffc55e16ec7c7f0b7e3327b25aaf287feba34cc527d93d40d5b59bb4a1976
4
+ data.tar.gz: cacc33604f6299450735d16a376d583ffea86f27cc04e6108eab92473ae2ac50
5
5
  SHA512:
6
- metadata.gz: afee5b7d9069bfda962b20776cbb38e0d9b0a416461cb9a41a7eae3c3aa1531d6e29dedebcd7210d1295b17ff9b1bce17fcf0d91bc516d3ff302f067f2f23461
7
- data.tar.gz: f595da01d69259e73d497aef6dee354d202d6bb413fb4e4dba240b1060fc6794352f4f43c16f6bc12f53ef553bbdce025bff5867ecfc2d6c770cdc73169fc09c
6
+ metadata.gz: aa791974d982def87dfff26bc03819e5cd9c12d25440a055a3c9ce3bb5ebf8c6b36d00f31f93b3b37d5f0702ce4d5831e47f86e24abea9efde01b6d40e8f9482
7
+ data.tar.gz: df472e7514f6308e4436f0e475ea0dbcbf1e5e3219d87a3bc7adddb9ea74ee198088f9d565db61925cad3865f24fa25d6d1ff9db7b85bc84122fb0d934c1dbac
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --require spec_helper
2
+ --format doc
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.13.0 (2023-11-07)
4
+
5
+ - Allow adding multiple routing keys to the consumer configuration, configure method within consumer will only accept `routing_keys` array instead of `routing_key` string
6
+
7
+ ## 0.12.0 (2023-10-26)
8
+
9
+ - add new interface to setup consumers including their exchange, queue and binding the queue to the exchange via routing key via `Ears.setup_consumers` and `configure(queue:, exchange:,routing_key:, ...)` for Ears::Consumers subclasses
10
+
3
11
  ## 0.11.2 (2023-10-25)
4
12
 
5
13
  - Add documentation generation via yard
data/Gemfile CHANGED
@@ -2,13 +2,13 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- group :development, :test do
6
- gem 'prettier'
5
+ group :test do
6
+ gem 'prettier', require: false
7
7
  gem 'rake'
8
- gem 'redcarpet'
9
8
  gem 'rspec'
10
- gem 'rubocop'
11
- gem 'rubocop-rake'
12
- gem 'rubocop-rspec'
13
- gem 'yard'
9
+ gem 'rubocop', require: false
10
+ gem 'rubocop-rake', require: false
11
+ gem 'rubocop-rspec', require: false
12
+ gem 'simplecov'
13
+ gem 'yard', require: false
14
14
  end
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ears (0.11.2)
4
+ ears (0.13.0)
5
5
  bunny (~> 2.22.0)
6
6
  multi_json
7
7
 
@@ -15,6 +15,7 @@ GEM
15
15
  amq-protocol (~> 2.3, >= 2.3.1)
16
16
  sorted_set (~> 1, >= 1.0.2)
17
17
  diff-lcs (1.5.0)
18
+ docile (1.4.0)
18
19
  haml (6.1.2)
19
20
  temple (>= 0.8.2)
20
21
  thor
@@ -36,7 +37,6 @@ GEM
36
37
  rake (13.0.6)
37
38
  rbs (3.1.3)
38
39
  rbtree (0.4.6)
39
- redcarpet (3.6.0)
40
40
  regexp_parser (2.8.1)
41
41
  rexml (3.2.6)
42
42
  rspec (3.12.0)
@@ -78,6 +78,12 @@ GEM
78
78
  rubocop-factory_bot (~> 2.22)
79
79
  ruby-progressbar (1.13.0)
80
80
  set (1.0.3)
81
+ simplecov (0.22.0)
82
+ docile (~> 1.1)
83
+ simplecov-html (~> 0.11)
84
+ simplecov_json_formatter (~> 0.1)
85
+ simplecov-html (0.12.3)
86
+ simplecov_json_formatter (0.1.4)
81
87
  sorted_set (1.0.3)
82
88
  rbtree
83
89
  set (~> 1.0)
@@ -101,6 +107,7 @@ PLATFORMS
101
107
  arm64-darwin-20
102
108
  arm64-darwin-21
103
109
  arm64-darwin-22
110
+ ruby
104
111
  x86_64-darwin-20
105
112
  x86_64-darwin-21
106
113
  x86_64-darwin-22
@@ -110,11 +117,11 @@ DEPENDENCIES
110
117
  ears!
111
118
  prettier
112
119
  rake
113
- redcarpet
114
120
  rspec
115
121
  rubocop
116
122
  rubocop-rake
117
123
  rubocop-rspec
124
+ simplecov
118
125
  yard
119
126
 
120
127
  BUNDLED WITH
data/README.md CHANGED
@@ -39,7 +39,39 @@ end
39
39
 
40
40
  _Note_: `connection_name` is a mandatory setting!
41
41
 
42
- Next, define your exchanges, queues, and consumers by calling `Ears.setup`.
42
+ Next, you can define your exchanges, queues, and consumers in 2 ways:
43
+
44
+ #### 1. consumer specific configuration method (recommended)
45
+
46
+ 1. Pass your consumer classes to `Ears.setup`:
47
+
48
+ ```ruby
49
+ Ears.setup do
50
+ Ears.setup_consumers(Consumer1, Consumer2, ...)
51
+ end
52
+ ```
53
+
54
+ 2. Implement your consumers by subclassing `Ears::Consumer`. and call the configure method.
55
+
56
+ ```ruby
57
+ class Consumer1 < Ears::Consumer
58
+ configure(
59
+ queue: 'queue_name',
60
+ exchange: 'exchange',
61
+ routing_keys: %w[routing_key1 routing_key2],
62
+ retry_queue: true, # optional configuration, defaults to false, Adds a retry queue
63
+ error_queue: true, # optional configuration, defaults to false, Adds an error queue
64
+ )
65
+ def work(delivery_info, metadata, payload)
66
+ message = JSON.parse(payload)
67
+ do_stuff(message)
68
+
69
+ ack
70
+ end
71
+ end
72
+ ```
73
+
74
+ #### 2. Generic configuration method
43
75
 
44
76
  ```ruby
45
77
  Ears.setup do
@@ -57,7 +89,7 @@ Ears.setup do
57
89
  end
58
90
  ```
59
91
 
60
- Finally, you need to implement `MyConsumer` by subclassing `Ears::Consumer`.
92
+ Finally, you need to implement `MyConsumer` by subclassing `Ears::Consumer`. and call the configure method.
61
93
 
62
94
  ```ruby
63
95
  class MyConsumer < Ears::Consumer
@@ -70,7 +102,9 @@ class MyConsumer < Ears::Consumer
70
102
  end
71
103
  ```
72
104
 
73
- And, do not forget to run it. Be prepared that unhandled errors will be reraised. So, take care of cleanup work.
105
+ ### Run your consumers
106
+
107
+ Note: Be prepared that unhandled errors will be reraised. So, take care of cleanup work.
74
108
 
75
109
  ```ruby
76
110
  begin
@@ -165,7 +199,24 @@ end
165
199
 
166
200
  ### Implementing a retrying queue
167
201
 
168
- Sometimes you want to automatically retry processing a message, in case it just failed due to temporary problems. In that case, you can set the `retry_queue` and `retry_delay` parameters when creating the queue.
202
+ Sometimes you want to automatically retry processing a message, in case it just failed due to temporary problems. In that case, you can set the `retry_queue` and `retry_delay` parameters when creating the queue OR pass it to the configure method in your consumer.
203
+
204
+ ```ruby
205
+ class MyConsumer < Ears::Consumer
206
+ configure(
207
+ queue: 'queue_name',
208
+ exchange: 'exchange',
209
+ routing_keys: %w[routing_key1 routing_key2],
210
+ retry_queue: true,
211
+ )
212
+ def work(delivery_info, metadata, payload)
213
+ message = JSON.parse(payload)
214
+ do_stuff(message)
215
+
216
+ ack
217
+ end
218
+ end
219
+ ```
169
220
 
170
221
  ```ruby
171
222
  my_queue =
@@ -178,7 +229,24 @@ This will happen indefinitely, so if you want to bail out of this cycle at some
178
229
 
179
230
  ### Implementing an error queue
180
231
 
181
- You can set the `error_queue` parameter to automatically create an error queue.
232
+ You can set the `error_queue` parameter to automatically create an error queue, or add it to the configure method in your consumer.
233
+
234
+ ```ruby
235
+ class MyConsumer < Ears::Consumer
236
+ configure(
237
+ queue: 'queue_name',
238
+ exchange: 'exchange',
239
+ routing_keys: %w[routing_key1 routing_key2],
240
+ error_queue: true,
241
+ )
242
+ def work(delivery_info, metadata, payload)
243
+ message = JSON.parse(payload)
244
+ do_stuff(message)
245
+
246
+ ack
247
+ end
248
+ end
249
+ ```
182
250
 
183
251
  ```ruby
184
252
  my_queue =
data/Rakefile CHANGED
@@ -2,13 +2,23 @@
2
2
 
3
3
  require 'rake/clean'
4
4
  require 'bundler/gem_tasks'
5
+ require 'rubocop'
6
+ require 'rubocop/rake_task'
5
7
  require 'rspec/core/rake_task'
6
8
  require 'yard'
7
9
 
8
10
  CLEAN << '.yardoc'
9
- CLOBBER << 'doc'
11
+ CLOBBER << 'doc' << 'coverage'
10
12
 
11
13
  RSpec::Core::RakeTask.new(:spec)
12
14
  YARD::Rake::YardocTask.new { |t| t.stats_options = %w[--list-undoc] }
13
15
 
14
- task default: :spec
16
+ RuboCop::RakeTask.new(:rubocop) do |task|
17
+ task.formatters = ['simple']
18
+ task.fail_on_error = true
19
+ end
20
+
21
+ desc 'Run Prettier'
22
+ task(:prettier) { sh 'npm run lint' }
23
+
24
+ task default: %i[spec rubocop prettier]
data/lib/ears/consumer.rb CHANGED
@@ -27,6 +27,29 @@ module Ears
27
27
  middlewares << middleware.new(opts)
28
28
  end
29
29
 
30
+ # Configures the consumer, setting queue, exchange and other options to be used by
31
+ # the add_consumer method.
32
+ #
33
+ # @param [Hash] opts The options to configure the consumer with.
34
+ # @option opts [String] :queue The name of the queue to consume from.
35
+ # @option opts [String] :exchange The name of the exchange the queue should be bound to.
36
+ # @option opts [Array] :routing_keys The routing keys used for the queue binding.
37
+ # @option opts [Boolean] :durable_queue (true) Whether the queue should be durable.
38
+ # @option opts [Boolean] :retry_queue (false) Whether a retry queue should be provided.
39
+ # @option opts [Integer] :retry_delay (5000) The delay in milliseconds before retrying a message.
40
+ # @option opts [Boolean] :error_queue (false) Whether an error queue should be provided.
41
+ # @option opts [Boolean] :durable_exchange (true) Whether the exchange should be durable.
42
+ # @option opts [Symbol] :exchange_type (:topic) The type of exchange to use.
43
+ # @option opts [Integer] :threads (1) The number of threads to use for this consumer.
44
+ def self.configure(opts = {})
45
+ self.queue = opts.fetch(:queue)
46
+ self.exchange = opts.fetch(:exchange)
47
+ self.routing_keys = opts.fetch(:routing_keys)
48
+ self.queue_options = queue_options_from(opts: opts)
49
+ self.durable_exchange = opts.fetch(:durable_exchange, true)
50
+ self.exchange_type = opts.fetch(:exchange_type, :topic)
51
+ end
52
+
30
53
  # The method that is called when a message from the queue is received.
31
54
  # Keep in mind that the parameters received can be altered by middlewares!
32
55
  #
@@ -101,5 +124,32 @@ module Ears
101
124
  raise InvalidReturnError, result
102
125
  end
103
126
  end
127
+
128
+ class << self
129
+ attr_reader :queue,
130
+ :exchange,
131
+ :routing_keys,
132
+ :queue_options,
133
+ :durable_exchange,
134
+ :exchange_type
135
+
136
+ private
137
+
138
+ def queue_options_from(opts:)
139
+ {
140
+ durable: opts.fetch(:durable_queue, true),
141
+ retry_queue: opts.fetch(:retry_queue, false),
142
+ retry_delay: opts.fetch(:retry_delay, 5000),
143
+ error_queue: opts.fetch(:error_queue, false),
144
+ }
145
+ end
146
+
147
+ attr_writer :queue,
148
+ :exchange,
149
+ :routing_keys,
150
+ :queue_options,
151
+ :durable_exchange,
152
+ :exchange_type
153
+ end
104
154
  end
105
155
  end
@@ -15,6 +15,7 @@ module Ears
15
15
 
16
16
  def call(delivery_info, metadata, payload, app)
17
17
  return handle_exceeded(payload) if retries_exceeded?(metadata)
18
+
18
19
  app.call(delivery_info, metadata, payload)
19
20
  end
20
21
 
data/lib/ears/setup.rb CHANGED
@@ -58,8 +58,34 @@ module Ears
58
58
  end
59
59
  end
60
60
 
61
+ # Sets up consumers, including bindings to exchanges and queues.
62
+ #
63
+ # @param [Array<Class<Ears::Consumer>>] consumer_classes An array of subclasses of {Ears::Consumer} that call {Ears::Consumer#configure} in their class definition.
64
+ def setup_consumers(*consumer_classes)
65
+ consumer_classes.each { |consumer_class| setup_consumer(consumer_class) }
66
+ end
67
+
61
68
  private
62
69
 
70
+ def setup_consumer(consumer_class)
71
+ exchange =
72
+ exchange(
73
+ consumer_class.exchange,
74
+ consumer_class.exchange_type,
75
+ durable: consumer_class.durable_exchange,
76
+ )
77
+ configured_queue =
78
+ queue(consumer_class.queue, consumer_class.queue_options)
79
+ bind_queue_to_routing_keys(consumer_class, exchange, configured_queue)
80
+ consumer(configured_queue, consumer_class)
81
+ end
82
+
83
+ def bind_queue_to_routing_keys(consumer_class, exchange, configured_queue)
84
+ consumer_class.routing_keys.each do |routing_key|
85
+ configured_queue.bind(exchange, routing_key: routing_key)
86
+ end
87
+ end
88
+
63
89
  def queue_options(bunny_opts, retry_arguments)
64
90
  return bunny_opts unless retry_arguments
65
91
 
data/lib/ears/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ears
2
- VERSION = '0.11.2'
2
+ VERSION = '0.13.0'
3
3
  end
data/lib/ears.rb CHANGED
@@ -8,7 +8,6 @@ require 'ears/version'
8
8
  module Ears
9
9
  class << self
10
10
  # The global configuration for Ears.
11
- #
12
11
  # @return [Ears::Configuration]
13
12
  def configuration
14
13
  @configuration ||= Ears::Configuration.new
@@ -48,6 +47,11 @@ module Ears
48
47
  Ears::Setup.new.instance_eval(&block)
49
48
  end
50
49
 
50
+ # Quick setup your consumers (including exchanges and queues).
51
+ def setup_consumers(*consumer_classes)
52
+ Ears::Setup.new.setup_consumers(*consumer_classes)
53
+ end
54
+
51
55
  # Blocks the calling thread until +SIGTERM+ or +SIGINT+ is received.
52
56
  # Used to keep the process alive while processing messages.
53
57
  def run!
@@ -74,9 +78,7 @@ module Ears
74
78
 
75
79
  # Used internally for testing.
76
80
  def reset!
77
- @connection = nil
78
- @configuration = nil
79
- Thread.current[:ears_channel] = nil
81
+ @configuration = @connection = Thread.current[:ears_channel] = nil
80
82
  end
81
83
 
82
84
  private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ears
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - InVision AG
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-25 00:00:00.000000000 Z
11
+ date: 2023-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bunny