deimos-ruby 2.4.0 → 2.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8ba2f3149ce2a7c10a5af09c4d7c07f25e33c8bac9f9783953e10bbbca5e74d
4
- data.tar.gz: 3a5a112a7886b3acdf0b1aa0f18f984fbe93aa9e83f6912a667aa1eb113bbc5d
3
+ metadata.gz: 7a0b8bc495e0ef1c93a1f3a7d4b721ecd0ec149df866c0281e572c032ba25de5
4
+ data.tar.gz: 9426813c28bb569ee16e1f453b9f636baf309197ed59a25a337146852aec029a
5
5
  SHA512:
6
- metadata.gz: e5796d8f41a4a6f86be7659d7dde670bc30651a32124fd2434ff90263fa418bb56478ef25e620e0b59a5e55d88c21d01e6ce77444b8b34aba523d924be452807
7
- data.tar.gz: 107c63551a2606108e02dc0414d6ade8466b53dc89f6a54af12e02a1eff76386c8f864aca7746c27c2ff1a8bfad279b40d8efeff01938f5f5b4ee55b737f30d3
6
+ metadata.gz: bc7752b7345504f327c2c415dc90c58b31a3d6a92175eef71c31dcb66ecc358d7580bc79d7cd6b78c2df71bc8a45fab554d89018d6d85c2d23f91d652569f55c
7
+ data.tar.gz: b21aead2768acf0045a91175405a38352763a6ed85b7adc78fc70bdf1ea6dbf4cd993a94ac038c1275e7be6821bd623ab2e5b665f4509d7ce299dfba465e964d
data/.rubocop.yml CHANGED
@@ -340,3 +340,8 @@ RSpec/SpecFilePathFormat:
340
340
  Security/YAMLLoad:
341
341
  Exclude:
342
342
  - 'lib/deimos.rb'
343
+
344
+ Style/OneClassPerFile:
345
+ Exclude:
346
+ - karafka.rb
347
+ - spec/spec_helper.rb
data/CHANGELOG.md CHANGED
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## Unreleased
9
+
10
+ ## 2.5.0 - 2026-03-04
11
+
12
+ - Breaking: `process_message?` in batch consumption now receives the full Kafka message object instead of just the payload, allowing tombstones to be identified via the message key and metadata.
13
+ - Breaking: `test_consume_batch` and `test_consume_message` will now raise an error if the topic is configured incorrectly (i.e. the `each_message` setting doesn't match the method used).
14
+
8
15
  ## 2.4.0 - 2026-03-02
9
16
 
10
17
  - Major change: Switch from using `avro_turf` and `proto_turf` to use `schema_registry_client`, which handles both Avro and Protobuf.
@@ -25,7 +25,7 @@ module Deimos
25
25
  # they are split
26
26
  # @return [void]
27
27
  def consume_batch
28
- filtered = messages.select { |p| process_message?(p.payload) }
28
+ filtered = messages.select { |message| process_message?(message) }
29
29
  skipped_count = messages.size - filtered.size
30
30
  if skipped_count.positive?
31
31
  Deimos::Logging.log_debug(
@@ -105,11 +105,14 @@ module Deimos
105
105
  message.payload.nil?
106
106
  end
107
107
 
108
- # Override this message to conditionally save records
109
- # @param _payload [Hash,Deimos::SchemaClass::Record] The kafka message
108
+ # Override this method to conditionally save records.
109
+ #
110
+ # This receives the full Kafka message so tombstones can still be
111
+ # identified and acted on using message metadata/key.
112
+ # @param _message [Karafka::Messages::Message] The Kafka message
110
113
  # @return [Boolean] if true, record is created/update.
111
114
  # If false, record processing is skipped but message offset is still committed.
112
- def process_message?(_payload)
115
+ def process_message?(_message)
113
116
  true
114
117
  end
115
118
  end
@@ -232,6 +232,9 @@ module Deimos
232
232
  else
233
233
  Deimos.topic_for_consumer(handler_class_or_topic)
234
234
  end
235
+
236
+ _validate_consumer_config(topic_name, single)
237
+
235
238
  consumer = karafka.consumer_for(topic_name)
236
239
 
237
240
  Deimos.karafka_config_for(topic: topic_name).each_message(single)
@@ -259,5 +262,25 @@ module Deimos
259
262
 
260
263
  consumer.consume
261
264
  end
265
+
266
+ private
267
+
268
+ # Validate that the consumer config matches the test method being called.
269
+ # @param topic_name [String]
270
+ # @param single [Boolean] true if testing single message consumption
271
+ # @return [void]
272
+ def _validate_consumer_config(topic_name, single)
273
+ config = Deimos.karafka_config_for(topic: topic_name)
274
+ return if config.nil?
275
+
276
+ each_message = config.each_message
277
+ if single && !each_message
278
+ raise "Topic #{topic_name} is not configured with `each_message true` but " \
279
+ 'you are trying to test with `test_consume_message`. Use `test_consume_batch` instead.'
280
+ elsif !single && each_message
281
+ raise "Topic #{topic_name} is configured with `each_message true` but " \
282
+ 'you are trying to test with `test_consume_batch`. Use `test_consume_message` instead.'
283
+ end
284
+ end
262
285
  end
263
286
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '2.4.0'
4
+ VERSION = '2.5.0'
5
5
  end
@@ -58,10 +58,10 @@ module ActiveRecordBatchConsumerTest
58
58
  record_class Widget
59
59
  compacted false
60
60
 
61
- def process_message?(payload)
62
- return true if payload.nil?
61
+ def process_message?(message)
62
+ return true if message.payload.nil?
63
63
 
64
- payload['test_id'] != 'skipme'
64
+ message.payload['test_id'] != 'skipme'
65
65
  end
66
66
  end
67
67
  end
@@ -853,8 +853,8 @@ module ActiveRecordBatchConsumerTest
853
853
  self.class.last_post_process_batch = messages
854
854
  end
855
855
 
856
- def process_message?(payload)
857
- payload['test_id'] != 'skipme'
856
+ def process_message?(message)
857
+ message.payload['test_id'] != 'skipme'
858
858
  end
859
859
  end
860
860
  end
@@ -135,18 +135,21 @@ module ActiveRecordConsumerTest
135
135
  schema 'MySchemaWithDateTimes'
136
136
  namespace 'com.my-namespace'
137
137
  key_config plain: true
138
+ each_message true
138
139
  end
139
140
  topic 'my-topic2' do
140
141
  consumer MyConsumerWithKey
141
142
  schema 'MySchemaWithDateTimes'
142
143
  namespace 'com.my-namespace'
143
144
  key_config schema: 'MySchemaId_key'
145
+ each_message true
144
146
  end
145
147
  topic 'my-topic3' do
146
148
  consumer MyCustomFetchConsumer
147
149
  schema 'MySchema'
148
150
  namespace 'com.my-namespace'
149
151
  key_config none: true
152
+ each_message true
150
153
  end
151
154
  end
152
155
  end
@@ -266,6 +269,7 @@ module ActiveRecordConsumerTest
266
269
  schema 'MySchema'
267
270
  namespace 'com.my-namespace'
268
271
  key_config plain: true
272
+ each_message true
269
273
  end
270
274
  end
271
275
 
@@ -33,6 +33,7 @@ module ConsumerTest
33
33
  namespace 'com.my-namespace'
34
34
  key_config field: 'test_id'
35
35
  consumer consumer_class
36
+ each_message true
36
37
  reraise_errors true
37
38
  use_schema_classes route_usc
38
39
  reraise_errors route_rre
@@ -91,6 +92,7 @@ module ConsumerTest
91
92
  namespace 'com.my-namespace'
92
93
  key_config plain: true
93
94
  consumer MyConsumer
95
+ each_message true
94
96
  reraise_errors true
95
97
  use_schema_classes use_schema_classes
96
98
  reraise_errors true
@@ -177,6 +179,7 @@ module ConsumerTest
177
179
  namespace 'com.my-namespace'
178
180
  key_config field: 'test_id'
179
181
  consumer consumer_class
182
+ each_message true
180
183
  reraise_errors true
181
184
  end
182
185
  end
@@ -217,6 +220,7 @@ module ConsumerTest
217
220
  namespace 'com.my-namespace'
218
221
  key_config field: 'test_id'
219
222
  consumer ConsumerTest::MyConsumer
223
+ each_message true
220
224
  reraise_errors true
221
225
  use_schema_classes true
222
226
  reraise_errors true
@@ -138,6 +138,7 @@ RSpec.describe Karafka::Routing::Topic do
138
138
  schema 'MySchema'
139
139
  namespace 'com.my-namespace'
140
140
  key_config({ field: :test_id })
141
+ each_message true
141
142
  end
142
143
  end
143
144
 
@@ -72,4 +72,56 @@ RSpec.describe Deimos::TestHelpers do
72
72
  end
73
73
  end
74
74
 
75
+ describe 'consumer config validation' do
76
+ let(:consumer_class) do
77
+ Class.new(Deimos::Consumer) do
78
+ def consume_message(message)
79
+ message.payload
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'when calling test_consume_message on a batch topic' do
85
+ before(:each) do
86
+ stub_const('MyBatchConsumer', consumer_class)
87
+ Karafka::App.routes.redraw do
88
+ topic 'my-batch-topic' do
89
+ consumer MyBatchConsumer
90
+ schema 'MySchema'
91
+ namespace 'com.my-namespace'
92
+ key_config field: 'test_id'
93
+ each_message false
94
+ end
95
+ end
96
+ end
97
+
98
+ it 'should raise an error' do
99
+ expect {
100
+ test_consume_message('my-batch-topic', { 'test_id' => 'foo', 'some_int' => 1 })
101
+ }.to raise_error(RuntimeError, /not configured with `each_message true`.*test_consume_batch/)
102
+ end
103
+ end
104
+
105
+ context 'when calling test_consume_batch on a single-message topic' do
106
+ before(:each) do
107
+ stub_const('MySingleConsumer', consumer_class)
108
+ Karafka::App.routes.redraw do
109
+ topic 'my-single-topic' do
110
+ consumer MySingleConsumer
111
+ schema 'MySchema'
112
+ namespace 'com.my-namespace'
113
+ key_config field: 'test_id'
114
+ each_message true
115
+ end
116
+ end
117
+ end
118
+
119
+ it 'should raise an error' do
120
+ expect {
121
+ test_consume_batch('my-single-topic', [{ 'test_id' => 'foo', 'some_int' => 1 }])
122
+ }.to raise_error(RuntimeError, /configured with `each_message true`.*test_consume_message/)
123
+ end
124
+ end
125
+ end
126
+
75
127
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deimos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner