sbmt-kafka_consumer 3.5.1 → 3.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 +4 -4
- data/.rubocop.yml +4 -0
- data/CHANGELOG.md +13 -0
- data/README.md +38 -2
- data/lib/sbmt/kafka_consumer/base_consumer.rb +27 -5
- data/lib/sbmt/kafka_consumer/config.rb +11 -0
- data/lib/sbmt/kafka_consumer/inbox_consumer.rb +2 -2
- data/lib/sbmt/kafka_consumer/instrumentation/logger_listener.rb +1 -0
- data/lib/sbmt/kafka_consumer/probes/probe.rb +1 -1
- data/lib/sbmt/kafka_consumer/version.rb +1 -1
- data/lib/sbmt/kafka_consumer.rb +8 -0
- data/sbmt-kafka_consumer.gemspec +1 -1
- metadata +5 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3acb66e582aa1dc634195368a85f0a9fba8857f1fe319614b7caa05f25ea1614
|
|
4
|
+
data.tar.gz: 393db4b5c06f1b587aa3c1cd2d61b6dc13b99eeb102b52aa359e865e2e7b78dd
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25c52294c777720e106a21e73eb35dd0c06dd1425ad2f0ab0286e046498506e8e7ebf7ba0032159abfd38ef4145d3746fea2dd6d1966445c006d220dc7018e92
|
|
7
|
+
data.tar.gz: bf2364f20485662e310ba80b45e6c6169d6966c30dc37ce49e60b071831e20a6667eccf747156de26751b2d9cd3320beebfa822cd8c883cf533dd5e950eab9e4
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
13
13
|
|
|
14
14
|
### Fixed
|
|
15
15
|
|
|
16
|
+
## [3.6.0] - 2025-12-02
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Allow middleware configuration for all consumers
|
|
21
|
+
- Added option `batch_midlewares` to add middleware before message batch processing
|
|
22
|
+
|
|
23
|
+
## [3.5.2] - 2025-07-21
|
|
24
|
+
|
|
25
|
+
### Changed
|
|
26
|
+
|
|
27
|
+
- Add Rack 3 support: unfreeze headers hash in probes response.
|
|
28
|
+
|
|
16
29
|
## [3.5.1] - 2025-04-18
|
|
17
30
|
|
|
18
31
|
### Fixed
|
data/README.md
CHANGED
|
@@ -185,10 +185,12 @@ consumer_groups:
|
|
|
185
185
|
|
|
186
186
|
- `skip_on_error` - optional, default false, omit consumer errors in message processing and commit the offset to Kafka
|
|
187
187
|
- `middlewares` - optional, default [], type String, add middleware before message processing
|
|
188
|
+
- `batch_middlewares` - optional, default [], type String, add middleware before batch message processing
|
|
188
189
|
|
|
189
190
|
```yaml
|
|
190
191
|
init_attrs:
|
|
191
192
|
middlewares: ['SomeMiddleware']
|
|
193
|
+
batch_middlewares: ['SomeBatchMiddleware']
|
|
192
194
|
```
|
|
193
195
|
|
|
194
196
|
```ruby
|
|
@@ -197,9 +199,16 @@ class SomeMiddleware
|
|
|
197
199
|
yield if message.payload.id.to_i % 2 == 0
|
|
198
200
|
end
|
|
199
201
|
end
|
|
202
|
+
|
|
203
|
+
class SomeBatchMiddleware
|
|
204
|
+
def call(message, consumer)
|
|
205
|
+
yield
|
|
206
|
+
end
|
|
207
|
+
end
|
|
200
208
|
```
|
|
201
209
|
__CAUTION__:
|
|
202
|
-
- ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message` method.
|
|
210
|
+
- ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message/process_batch` method.
|
|
211
|
+
- ⚠️ all middlewares must take either 1 or 2 parameters.
|
|
203
212
|
|
|
204
213
|
#### `consumer.init_attrs` options for `InboxConsumer`
|
|
205
214
|
|
|
@@ -207,10 +216,12 @@ __CAUTION__:
|
|
|
207
216
|
- `event_name` - optional, default nil, used when the inbox item keep several event types
|
|
208
217
|
- `skip_on_error` - optional, default false, omit consumer errors in message processing and commit the offset to Kafka
|
|
209
218
|
- `middlewares` - optional, default [], type String, add middleware before message processing
|
|
219
|
+
- `batch_middlewares` - optional, default [], type String, add middleware before batch message processing
|
|
210
220
|
|
|
211
221
|
```yaml
|
|
212
222
|
init_attrs:
|
|
213
223
|
middlewares: ['SomeMiddleware']
|
|
224
|
+
batch_middlewares: ['SomeBatchMiddleware']
|
|
214
225
|
```
|
|
215
226
|
|
|
216
227
|
```ruby
|
|
@@ -219,15 +230,40 @@ class SomeMiddleware
|
|
|
219
230
|
yield if message.payload.id.to_i % 2 == 0
|
|
220
231
|
end
|
|
221
232
|
end
|
|
233
|
+
|
|
234
|
+
class SomeBatchMiddleware
|
|
235
|
+
def call(message, consumer)
|
|
236
|
+
yield
|
|
237
|
+
end
|
|
238
|
+
end
|
|
222
239
|
```
|
|
223
240
|
__CAUTION__:
|
|
224
241
|
- ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message` method.
|
|
225
|
-
- ⚠️
|
|
242
|
+
- ⚠️ all middlewares must take either 1 or 2 parameters.
|
|
226
243
|
|
|
227
244
|
#### `deserializer.init_attrs` options
|
|
228
245
|
|
|
229
246
|
- `skip_decoding_error` — don't raise an exception when cannot deserialize the message
|
|
230
247
|
|
|
248
|
+
### Middlewares for all consumersа
|
|
249
|
+
|
|
250
|
+
To add middleware for all consumers, define them in the configuration
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
# config/initializers/kafka_consumer.rb
|
|
254
|
+
|
|
255
|
+
Sbmt::KafkaConsumer.process_message_middlewares.push(
|
|
256
|
+
SomeMiddleware
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
Sbmt::KafkaConsumer.process_batch_middlewares(
|
|
260
|
+
SomeBatchMiddleware
|
|
261
|
+
)
|
|
262
|
+
```
|
|
263
|
+
__CAUTION__:
|
|
264
|
+
- ⚠️ `yield` is mandatory for all middleware, as it returns control to the `process_message` method.
|
|
265
|
+
- ⚠️ all middlewares must take either 1 or 2 parameters.
|
|
266
|
+
|
|
231
267
|
### `probes` config section
|
|
232
268
|
|
|
233
269
|
In Kubernetes, probes are mechanisms used to assess the health of your application running within a container.
|
|
@@ -5,8 +5,9 @@ module Sbmt
|
|
|
5
5
|
class BaseConsumer < Karafka::BaseConsumer
|
|
6
6
|
class_attribute :skip_on_error, instance_writer: false, default: false
|
|
7
7
|
class_attribute :middlewares, instance_writer: false, default: []
|
|
8
|
+
class_attribute :batch_middlewares, instance_writer: false, default: []
|
|
8
9
|
|
|
9
|
-
def self.consumer_klass(skip_on_error: nil, middlewares: nil)
|
|
10
|
+
def self.consumer_klass(skip_on_error: nil, middlewares: nil, batch_middlewares: nil)
|
|
10
11
|
klass = Class.new(self) do
|
|
11
12
|
def self.name
|
|
12
13
|
superclass.name
|
|
@@ -16,6 +17,7 @@ module Sbmt
|
|
|
16
17
|
# defaults are set in class_attribute definition
|
|
17
18
|
klass.skip_on_error = skip_on_error if skip_on_error
|
|
18
19
|
klass.middlewares = middlewares.map(&:constantize) if middlewares
|
|
20
|
+
klass.batch_middlewares = batch_middlewares.map(&:constantize) if batch_middlewares
|
|
19
21
|
klass
|
|
20
22
|
end
|
|
21
23
|
|
|
@@ -23,7 +25,7 @@ module Sbmt
|
|
|
23
25
|
::Rails.application.executor.wrap do
|
|
24
26
|
if process_batch?
|
|
25
27
|
with_batch_instrumentation(messages) do
|
|
26
|
-
|
|
28
|
+
do_process_batch(messages)
|
|
27
29
|
mark_message(messages.last)
|
|
28
30
|
end
|
|
29
31
|
else
|
|
@@ -99,6 +101,11 @@ module Sbmt
|
|
|
99
101
|
end
|
|
100
102
|
end
|
|
101
103
|
|
|
104
|
+
def do_process_batch(messages)
|
|
105
|
+
middleware_list = process_batch_middlewares + batch_middlewares
|
|
106
|
+
call_middlewares(messages, middleware_list) { process_batch(messages) }
|
|
107
|
+
end
|
|
108
|
+
|
|
102
109
|
def do_consume(message)
|
|
103
110
|
log_message(message) if log_payload?
|
|
104
111
|
|
|
@@ -107,7 +114,8 @@ module Sbmt
|
|
|
107
114
|
message.payload
|
|
108
115
|
|
|
109
116
|
with_common_instrumentation("process_message", message) do
|
|
110
|
-
|
|
117
|
+
middleware_list = process_message_middlewares + middlewares
|
|
118
|
+
call_middlewares(message, middleware_list) { process_message(message) }
|
|
111
119
|
end
|
|
112
120
|
|
|
113
121
|
with_common_instrumentation("mark_as_consumed", message) do
|
|
@@ -147,7 +155,7 @@ module Sbmt
|
|
|
147
155
|
message.payload || message.raw_payload
|
|
148
156
|
end
|
|
149
157
|
|
|
150
|
-
def call_middlewares(
|
|
158
|
+
def call_middlewares(payload, middlewares)
|
|
151
159
|
return yield if middlewares.empty?
|
|
152
160
|
|
|
153
161
|
chain = middlewares.map { |middleware_class| middleware_class.new }
|
|
@@ -156,7 +164,13 @@ module Sbmt
|
|
|
156
164
|
if chain.empty?
|
|
157
165
|
yield
|
|
158
166
|
else
|
|
159
|
-
chain.shift
|
|
167
|
+
middleware = chain.shift
|
|
168
|
+
|
|
169
|
+
if middleware.method(:call).arity == 2
|
|
170
|
+
middleware.call(payload, self, &traverse_chain)
|
|
171
|
+
else
|
|
172
|
+
middleware.call(payload, &traverse_chain)
|
|
173
|
+
end
|
|
160
174
|
end
|
|
161
175
|
end
|
|
162
176
|
traverse_chain.call
|
|
@@ -174,6 +188,14 @@ module Sbmt
|
|
|
174
188
|
@config ||= Sbmt::KafkaConsumer::Config.new
|
|
175
189
|
end
|
|
176
190
|
|
|
191
|
+
def process_message_middlewares
|
|
192
|
+
@process_message_middlewares ||= config.process_message_middlewares
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def process_batch_middlewares
|
|
196
|
+
@process_batch_middlewares ||= config.process_batch_middlewares
|
|
197
|
+
end
|
|
198
|
+
|
|
177
199
|
def cooperative_sticky?
|
|
178
200
|
config.partition_assignment_strategy == "cooperative-sticky"
|
|
179
201
|
end
|
|
@@ -27,6 +27,7 @@ class Sbmt::KafkaConsumer::Config < Anyway::Config
|
|
|
27
27
|
:pause_timeout, :pause_max_timeout, :pause_with_exponential_backoff,
|
|
28
28
|
:max_wait_time, :shutdown_timeout, :partition_assignment_strategy,
|
|
29
29
|
concurrency: 4, auth: {}, kafka: {}, consumer_groups: {}, probes: {}, metrics: {},
|
|
30
|
+
process_message_middlewares: [], process_batch_middlewares: [],
|
|
30
31
|
deserializer_class: "::Sbmt::KafkaConsumer::Serialization::NullDeserializer",
|
|
31
32
|
monitor_class: "::Sbmt::KafkaConsumer::Instrumentation::TracingMonitor",
|
|
32
33
|
logger_class: "::Sbmt::KafkaConsumer::Logger",
|
|
@@ -38,6 +39,8 @@ class Sbmt::KafkaConsumer::Config < Anyway::Config
|
|
|
38
39
|
|
|
39
40
|
on_load :validate_consumer_groups
|
|
40
41
|
on_load :set_default_metrics_port
|
|
42
|
+
on_load :set_process_message_middlewares
|
|
43
|
+
on_load :set_process_batch_middlewares
|
|
41
44
|
|
|
42
45
|
coerce_types client_id: :string,
|
|
43
46
|
pause_timeout: :integer,
|
|
@@ -80,4 +83,12 @@ class Sbmt::KafkaConsumer::Config < Anyway::Config
|
|
|
80
83
|
def set_default_metrics_port
|
|
81
84
|
self.metrics = metrics.new(port: probes.port) unless metrics.port
|
|
82
85
|
end
|
|
86
|
+
|
|
87
|
+
def set_process_message_middlewares
|
|
88
|
+
self.process_message_middlewares = Sbmt::KafkaConsumer.process_message_middlewares || []
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def set_process_batch_middlewares
|
|
92
|
+
self.process_batch_middlewares = Sbmt::KafkaConsumer.process_batch_middlewares || []
|
|
93
|
+
end
|
|
83
94
|
end
|
|
@@ -9,9 +9,9 @@ module Sbmt
|
|
|
9
9
|
class_attribute :inbox_item_class, instance_writer: false, default: nil
|
|
10
10
|
class_attribute :event_name, instance_writer: false, default: nil
|
|
11
11
|
|
|
12
|
-
def self.consumer_klass(inbox_item:, event_name: nil, skip_on_error: nil, name: nil, middlewares: nil)
|
|
12
|
+
def self.consumer_klass(inbox_item:, event_name: nil, skip_on_error: nil, name: nil, middlewares: nil, batch_middlewares: nil)
|
|
13
13
|
# defaults are set in class_attribute definition
|
|
14
|
-
klass = super(skip_on_error: skip_on_error, middlewares: middlewares)
|
|
14
|
+
klass = super(skip_on_error: skip_on_error, middlewares: middlewares, batch_middlewares: batch_middlewares)
|
|
15
15
|
klass.inbox_item_class = inbox_item.constantize
|
|
16
16
|
klass.event_name = event_name if event_name
|
|
17
17
|
klass
|
data/lib/sbmt/kafka_consumer.rb
CHANGED
|
@@ -26,6 +26,14 @@ module Sbmt
|
|
|
26
26
|
def logger
|
|
27
27
|
@logger ||= Rails.logger
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
def process_message_middlewares
|
|
31
|
+
@process_message_middlewares ||= []
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def process_batch_middlewares
|
|
35
|
+
@process_batch_middlewares ||= []
|
|
36
|
+
end
|
|
29
37
|
end
|
|
30
38
|
|
|
31
39
|
class Error < StandardError; end
|
data/sbmt-kafka_consumer.gemspec
CHANGED
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
|
33
33
|
|
|
34
34
|
spec.add_dependency "rails", ">= 6.1"
|
|
35
35
|
spec.add_dependency "zeitwerk", "~> 2.3"
|
|
36
|
-
spec.add_dependency "karafka", "~> 2.4"
|
|
36
|
+
spec.add_dependency "karafka", "~> 2.4.0"
|
|
37
37
|
spec.add_dependency "yabeda", ">= 0.11"
|
|
38
38
|
spec.add_dependency "anyway_config", ">= 2.4.0"
|
|
39
39
|
spec.add_dependency "thor"
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sbmt-kafka_consumer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Kuper Ruby-Platform Team
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -44,14 +43,14 @@ dependencies:
|
|
|
44
43
|
requirements:
|
|
45
44
|
- - "~>"
|
|
46
45
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
46
|
+
version: 2.4.0
|
|
48
47
|
type: :runtime
|
|
49
48
|
prerelease: false
|
|
50
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
50
|
requirements:
|
|
52
51
|
- - "~>"
|
|
53
52
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
53
|
+
version: 2.4.0
|
|
55
54
|
- !ruby/object:Gem::Dependency
|
|
56
55
|
name: yabeda
|
|
57
56
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -460,7 +459,6 @@ dependencies:
|
|
|
460
459
|
version: '0'
|
|
461
460
|
description: This gem is used for consuming Kafka messages. It represents a wrapper
|
|
462
461
|
over Karafka gem and is recommended for using as a transport with sbmt-outbox
|
|
463
|
-
email:
|
|
464
462
|
executables:
|
|
465
463
|
- kafka_consumer
|
|
466
464
|
extensions: []
|
|
@@ -550,7 +548,6 @@ metadata:
|
|
|
550
548
|
source_code_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer
|
|
551
549
|
changelog_uri: https://github.com/Kuper-Tech/sbmt-kafka_consumer/blob/master/CHANGELOG.md
|
|
552
550
|
rubygems_mfa_required: 'false'
|
|
553
|
-
post_install_message:
|
|
554
551
|
rdoc_options: []
|
|
555
552
|
require_paths:
|
|
556
553
|
- lib
|
|
@@ -565,8 +562,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
565
562
|
- !ruby/object:Gem::Version
|
|
566
563
|
version: '0'
|
|
567
564
|
requirements: []
|
|
568
|
-
rubygems_version: 3.
|
|
569
|
-
signing_key:
|
|
565
|
+
rubygems_version: 3.6.9
|
|
570
566
|
specification_version: 4
|
|
571
567
|
summary: Ruby gem for consuming Kafka messages
|
|
572
568
|
test_files: []
|