sbmt-kafka_consumer 2.3.0 → 2.4.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: 466c2702a664bfe4ad5916c115dddb574e2108a990af6b686c5eea3298fd3a4c
4
- data.tar.gz: 140e5ea106e9374df42dab0e372be5ff3c547a33882391a4634e368fc93b8737
3
+ metadata.gz: 3aaf5a3d0cab0fe477ab5af189b754b642c403036eec6f7329818645a1dff362
4
+ data.tar.gz: f198d12579b3437f903fff1c7be33246c5121b1b37bb735e861c7c0f9cbb0314
5
5
  SHA512:
6
- metadata.gz: fc45d190f2cd0646049392a75c3f7d1a77db081669855f13b4d3dedb6f1a143cea6830659dbff9273fbde5517e3f11259e127ecb6c5a48a08cd4f6c71bbd93ea
7
- data.tar.gz: 852f8c6da38cdb110cb5832d85f9798001f9b2fbf3db56c5b492cca4e44dcb3fc47639b60e4e5d143c8420a0b3f0c7e1467433f31861100c0578de62c6f49bec
6
+ metadata.gz: 468be419229e1096fbae7a0892607c33c8913f686478bca5d8ed8816ac83c8932be7683eedbfbc8eeb55225578dd74707c7bc256947691e65fa19d7142fdb095
7
+ data.tar.gz: 105b7fdd0b37927b92e81819035442705e9a636828469f47b61ce5bb67850db2f1c921e5d45b9bcadedb89eaceb6e929a3fde903672517a9aae5810e68ef0627
data/CHANGELOG.md CHANGED
@@ -13,6 +13,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
13
13
 
14
14
  ### Fixed
15
15
 
16
+ ## [2.4.0] - 2024-06-06
17
+
18
+ ### Added
19
+
20
+ - Added option `midlewares` to add middleware before message processing
21
+
22
+ ## [2.3.1] - 2024-06-05
23
+
24
+ ### Fixed
25
+
26
+ - Rename from `export_batch` to `process_batch`
27
+
16
28
  ## [2.3.0] - 2024-05-30
17
29
 
18
30
  ### Added
data/README.md CHANGED
@@ -183,12 +183,45 @@ consumer_groups:
183
183
  #### `consumer.init_attrs` options for `BaseConsumer`
184
184
 
185
185
  - `skip_on_error` - optional, default false, omit consumer errors in message processing and commit the offset to Kafka
186
+ - `middlewares` - optional, default [], type String, add middleware before message processing
187
+
188
+ ```yaml
189
+ init_attrs:
190
+ middlewares: ['SomeMiddleware']
191
+ ```
192
+
193
+ ```ruby
194
+ class SomeMiddleware
195
+ def call(message)
196
+ yield if message.payload.id.to_i % 2 == 0
197
+ end
198
+ end
199
+ ```
200
+ __CAUTION__:
201
+ - ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message` method.
186
202
 
187
203
  #### `consumer.init_attrs` options for `InboxConsumer`
188
204
 
189
205
  - `inbox_item` - required, name of the inbox item class
190
206
  - `event_name` - optional, default nil, used when the inbox item keep several event types
191
207
  - `skip_on_error` - optional, default false, omit consumer errors in message processing and commit the offset to Kafka
208
+ - `middlewares` - optional, default [], type String, add middleware before message processing
209
+
210
+ ```yaml
211
+ init_attrs:
212
+ middlewares: ['SomeMiddleware']
213
+ ```
214
+
215
+ ```ruby
216
+ class SomeMiddleware
217
+ def call(message)
218
+ yield if message.payload.id.to_i % 2 == 0
219
+ end
220
+ end
221
+ ```
222
+ __CAUTION__:
223
+ - ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message` method.
224
+ - ⚠️ Doesn't work with `process_batch`.
192
225
 
193
226
  #### `deserializer.init_attrs` options
194
227
 
@@ -233,14 +266,14 @@ require_relative "config/environment"
233
266
  some-extra-configuration
234
267
  ```
235
268
 
236
- ### `Export batch`
269
+ ### `Process batch`
237
270
 
238
- To process messages in batches, you need to add the `export_batch` method in the consumer
271
+ To process messages in batches, you need to add the `process_batch` method in the consumer
239
272
 
240
273
  ```ruby
241
274
  # app/consumers/some_consumer.rb
242
275
  class SomeConsumer < Sbmt::KafkaConsumer::BaseConsumer
243
- def export_batch(messages)
276
+ def process_batch(messages)
244
277
  # some code
245
278
  end
246
279
  end
@@ -5,9 +5,10 @@ module Sbmt
5
5
  class BaseConsumer < Karafka::BaseConsumer
6
6
  attr_reader :trace_id
7
7
 
8
- def self.consumer_klass(skip_on_error: false)
8
+ def self.consumer_klass(skip_on_error: false, middlewares: [])
9
9
  Class.new(self) do
10
10
  const_set(:SKIP_ON_ERROR, skip_on_error)
11
+ const_set(:MIDDLEWARES, middlewares.map(&:constantize))
11
12
 
12
13
  def self.name
13
14
  superclass.name
@@ -17,9 +18,9 @@ module Sbmt
17
18
 
18
19
  def consume
19
20
  ::Rails.application.executor.wrap do
20
- if export_batch?
21
+ if process_batch?
21
22
  with_batch_instrumentation(messages) do
22
- export_batch(messages)
23
+ process_batch(messages)
23
24
  mark_as_consumed!(messages.last)
24
25
  end
25
26
  else
@@ -30,11 +31,11 @@ module Sbmt
30
31
  end
31
32
  end
32
33
 
33
- def export_batch?
34
- if @export_batch_memoized.nil?
35
- @export_batch_memoized = respond_to?(:export_batch)
34
+ def process_batch?
35
+ if @process_batch_memoized.nil?
36
+ @process_batch_memoized = respond_to?(:process_batch)
36
37
  end
37
- @export_batch_memoized
38
+ @process_batch_memoized
38
39
  end
39
40
 
40
41
  private
@@ -93,7 +94,7 @@ module Sbmt
93
94
  # so we trigger it explicitly to catch undeserializable message early
94
95
  message.payload
95
96
 
96
- process_message(message)
97
+ call_middlewares(message, middlewares) { process_message(message) }
97
98
 
98
99
  mark_as_consumed!(message)
99
100
  end
@@ -102,6 +103,10 @@ module Sbmt
102
103
  self.class::SKIP_ON_ERROR
103
104
  end
104
105
 
106
+ def middlewares
107
+ self.class::MIDDLEWARES
108
+ end
109
+
105
110
  # can be overridden in consumer to enable message logging
106
111
  def log_payload?
107
112
  false
@@ -132,6 +137,21 @@ module Sbmt
132
137
  def message_payload(message)
133
138
  message.payload || message.raw_payload
134
139
  end
140
+
141
+ def call_middlewares(message, middlewares)
142
+ return yield if middlewares.empty?
143
+
144
+ chain = middlewares.map { |middleware_class| middleware_class.new }
145
+
146
+ traverse_chain = proc do
147
+ if chain.empty?
148
+ yield
149
+ else
150
+ chain.shift.call(message, &traverse_chain)
151
+ end
152
+ end
153
+ traverse_chain.call
154
+ end
135
155
  end
136
156
  end
137
157
  end
@@ -6,11 +6,12 @@ module Sbmt
6
6
  IDEMPOTENCY_HEADER_NAME = "Idempotency-Key"
7
7
  DEFAULT_SOURCE = "KAFKA"
8
8
 
9
- def self.consumer_klass(inbox_item:, event_name: nil, skip_on_error: false, name: nil)
9
+ def self.consumer_klass(inbox_item:, event_name: nil, skip_on_error: false, name: nil, middlewares: [])
10
10
  Class.new(self) do
11
11
  const_set(:INBOX_ITEM_CLASS_NAME, inbox_item)
12
12
  const_set(:EVENT_NAME, event_name)
13
13
  const_set(:SKIP_ON_ERROR, skip_on_error)
14
+ const_set(:MIDDLEWARES, middlewares.map(&:constantize))
14
15
 
15
16
  def self.name
16
17
  superclass.name
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Sbmt
4
4
  module KafkaConsumer
5
- VERSION = "2.3.0"
5
+ VERSION = "2.4.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sbmt-kafka_consumer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sbermarket Ruby-Platform Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-04 00:00:00.000000000 Z
11
+ date: 2024-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails