deimos-ruby 1.22.4 → 1.23.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.
@@ -91,7 +91,8 @@ describe Deimos, 'configuration' do
91
91
  heartbeat_interval: 10,
92
92
  handler: 'ConsumerTest::MyConsumer',
93
93
  use_schema_classes: nil,
94
- max_db_batch_size: nil
94
+ max_db_batch_size: nil,
95
+ bulk_import_id_generator: nil
95
96
  }, {
96
97
  topic: 'my_batch_consume_topic',
97
98
  group_id: 'my_batch_group_id',
@@ -109,7 +110,8 @@ describe Deimos, 'configuration' do
109
110
  heartbeat_interval: 10,
110
111
  handler: 'ConsumerTest::MyBatchConsumer',
111
112
  use_schema_classes: nil,
112
- max_db_batch_size: nil
113
+ max_db_batch_size: nil,
114
+ bulk_import_id_generator: nil
113
115
  }
114
116
  ],
115
117
  producer: {
@@ -261,7 +263,8 @@ describe Deimos, 'configuration' do
261
263
  heartbeat_interval: 13,
262
264
  handler: 'MyConfigConsumer',
263
265
  use_schema_classes: false,
264
- max_db_batch_size: nil
266
+ max_db_batch_size: nil,
267
+ bulk_import_id_generator: nil
265
268
  }
266
269
  ],
267
270
  producer: {
@@ -279,4 +282,40 @@ describe Deimos, 'configuration' do
279
282
  }
280
283
  )
281
284
  end
285
+
286
+ it 'should override global configurations' do
287
+ described_class.configure do
288
+ consumers.bulk_import_id_generator(-> { 'global' })
289
+ consumers.replace_associations true
290
+
291
+ consumer do
292
+ class_name 'MyConfigConsumer'
293
+ schema 'blah'
294
+ topic 'blah'
295
+ group_id 'myconsumerid'
296
+ bulk_import_id_generator(-> { 'consumer' })
297
+ replace_associations false
298
+ end
299
+
300
+ consumer do
301
+ class_name 'MyConfigConsumer2'
302
+ schema 'blah'
303
+ topic 'blah'
304
+ group_id 'myconsumerid'
305
+ end
306
+ end
307
+
308
+ consumers = described_class.config.consumers
309
+ expect(consumers.replace_associations).to eq(true)
310
+ expect(consumers.bulk_import_id_generator.call).to eq('global')
311
+
312
+ custom = MyConfigConsumer.config
313
+ expect(custom[:replace_associations]).to eq(false)
314
+ expect(custom[:bulk_import_id_generator].call).to eq('consumer')
315
+
316
+ default = MyConfigConsumer2.config
317
+ expect(default[:replace_associations]).to eq(true)
318
+ expect(default[:bulk_import_id_generator].call).to eq('global')
319
+
320
+ end
282
321
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # :nodoc:
4
+ # rubocop:disable Metrics/ModuleLength
4
5
  module ConsumerTest
5
6
  describe Deimos::Consumer, 'Message Consumer' do
6
7
  prepend_before(:each) do
@@ -26,8 +27,12 @@ module ConsumerTest
26
27
  describe 'consume' do
27
28
  SCHEMA_CLASS_SETTINGS.each do |setting, use_schema_classes|
28
29
  context "with Schema Class consumption #{setting}" do
30
+
29
31
  before(:each) do
30
- Deimos.configure { |config| config.schema.use_schema_classes = use_schema_classes }
32
+ Deimos.configure do |config|
33
+ config.schema.use_schema_classes = use_schema_classes
34
+ config.schema.generate_namespace_folders = true
35
+ end
31
36
  end
32
37
 
33
38
  it 'should consume a message' do
@@ -127,6 +132,41 @@ module ConsumerTest
127
132
  end
128
133
  end
129
134
  end
135
+
136
+ context 'with overriden schema classes' do
137
+
138
+ before(:each) do
139
+ Deimos.configure do |config|
140
+ config.schema.use_schema_classes = true
141
+ config.schema.generate_namespace_folders = true
142
+ end
143
+ end
144
+
145
+ prepend_before(:each) do
146
+ consumer_class = Class.new(described_class) do
147
+ schema 'MyUpdatedSchema'
148
+ namespace 'com.my-namespace'
149
+ key_config field: 'test_id'
150
+
151
+ # :nodoc:
152
+ def consume(_payload, _metadata)
153
+ raise 'This should not be called unless call_original is set'
154
+ end
155
+ end
156
+ stub_const('ConsumerTest::MyConsumer', consumer_class)
157
+ end
158
+
159
+ it 'should consume messages' do
160
+ test_consume_message('my_consume_topic',
161
+ { 'test_id' => 'foo',
162
+ 'some_int' => 1 }) do |payload, _metadata|
163
+ expect(payload['test_id']).to eq('foo')
164
+ expect(payload['some_int']).to eq(1)
165
+ expect(payload['super_int']).to eq(9000)
166
+ end
167
+ end
168
+
169
+ end
130
170
  end
131
171
 
132
172
  describe 'decode_key' do
@@ -218,3 +258,4 @@ module ConsumerTest
218
258
  end
219
259
  end
220
260
  end
261
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is autogenerated by Deimos, Do NOT modify
4
+ module Schemas; module MyNamespace
5
+ ### Primary Schema Class ###
6
+ # Autogenerated Schema for Record at com.my-namespace.MySchema
7
+ class MyUpdatedSchema < Schemas::MyNamespace::MySchema
8
+
9
+ attr_accessor :super_int
10
+
11
+ def initialize(test_id: nil,
12
+ some_int: nil)
13
+ super
14
+ self.super_int = some_int.nil? ? 10 : some_int * 9000
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,12 +2,13 @@
2
2
 
3
3
  each_db_config(Deimos::Utils::DbProducer) do
4
4
  let(:producer) do
5
- producer = described_class.new
5
+ producer = described_class.new(logger)
6
6
  allow(producer).to receive(:sleep)
7
7
  allow(producer).to receive(:producer).and_return(phobos_producer)
8
8
  producer
9
9
  end
10
10
 
11
+ let(:logger) { nil }
11
12
  let(:phobos_producer) do
12
13
  pp = instance_double(Phobos::Producer::PublicAPI)
13
14
  allow(pp).to receive(:publish_list)
@@ -308,35 +309,6 @@ each_db_config(Deimos::Utils::DbProducer) do
308
309
  Deimos.unsubscribe(subscriber)
309
310
  end
310
311
 
311
- it 'should delete messages on buffer overflow' do
312
- messages = (1..4).map do |i|
313
- Deimos::KafkaMessage.create!(
314
- id: i,
315
- topic: 'my-topic',
316
- message: "mess#{i}",
317
- partition_key: "key#{i}"
318
- )
319
- end
320
- (5..8).each do |i|
321
- Deimos::KafkaMessage.create!(
322
- id: i,
323
- topic: 'my-topic2',
324
- message: "mess#{i}",
325
- partition_key: "key#{i}"
326
- )
327
- end
328
-
329
- expect(Deimos::KafkaTopicInfo).to receive(:lock).
330
- with('my-topic', 'abc').and_return(true)
331
- expect(producer).to receive(:produce_messages).and_raise(Kafka::BufferOverflow)
332
- expect(producer).to receive(:retrieve_messages).and_return(messages)
333
- expect(Deimos::KafkaTopicInfo).to receive(:register_error)
334
-
335
- expect(Deimos::KafkaMessage.count).to eq(8)
336
- producer.process_topic('my-topic')
337
- expect(Deimos::KafkaMessage.count).to eq(4)
338
- end
339
-
340
312
  it 'should retry deletes and not re-publish' do
341
313
  messages = (1..4).map do |i|
342
314
  Deimos::KafkaMessage.create!(
@@ -388,6 +360,102 @@ each_db_config(Deimos::Utils::DbProducer) do
388
360
  expect { producer.delete_messages(messages) }.to raise_exception('OH NOES')
389
361
  end
390
362
 
363
+ context 'with buffer overflow exception' do
364
+ let(:messages) do
365
+ (1..4).map do |i|
366
+ Deimos::KafkaMessage.create!(
367
+ id: i,
368
+ key: i,
369
+ topic: 'my-topic',
370
+ message: { message: "mess#{i}" },
371
+ partition_key: "key#{i}"
372
+ )
373
+ end
374
+ end
375
+ let(:logger) do
376
+ logger = instance_double(Logger)
377
+ allow(logger).to receive(:error)
378
+ logger
379
+ end
380
+ let(:message_producer) do
381
+ Deimos.config.schema.backend = :mock
382
+ Deimos::ActiveRecordProducer.topic('my-topic')
383
+ Deimos::ActiveRecordProducer.key_config
384
+ Deimos::ActiveRecordProducer
385
+ end
386
+
387
+ around(:each) do |example|
388
+ config = Deimos::ActiveRecordProducer.config.clone
389
+ backend = Deimos.config.schema.backend
390
+
391
+ example.run
392
+ ensure
393
+ Deimos::ActiveRecordProducer.instance_variable_set(:@config, config)
394
+ Deimos.config.schema.backend = backend
395
+ end
396
+
397
+ before(:each) do
398
+ message_producer
399
+ (5..8).each do |i|
400
+ Deimos::KafkaMessage.create!(
401
+ id: i,
402
+ topic: 'my-topic2',
403
+ message: "mess#{i}",
404
+ partition_key: "key#{i}"
405
+ )
406
+ end
407
+ allow(Deimos::KafkaTopicInfo).to receive(:lock).
408
+ with('my-topic', 'abc').and_return(true)
409
+ allow(producer).to receive(:produce_messages).and_raise(Kafka::BufferOverflow)
410
+ allow(producer).to receive(:retrieve_messages).and_return(messages)
411
+ allow(Deimos::KafkaTopicInfo).to receive(:register_error)
412
+ end
413
+
414
+ it 'should delete messages on buffer overflow' do
415
+ expect(Deimos::KafkaMessage.count).to eq(8)
416
+ producer.process_topic('my-topic')
417
+ expect(Deimos::KafkaMessage.count).to eq(4)
418
+ end
419
+
420
+ it 'should notify on buffer overflow' do
421
+ subscriber = Deimos.subscribe('db_producer.produce') do |event|
422
+ expect(event.payload[:exception_object].message).to eq('Kafka::BufferOverflow')
423
+ expect(event.payload[:messages]).to eq(messages)
424
+ end
425
+ producer.process_topic('my-topic')
426
+ Deimos.unsubscribe(subscriber)
427
+ expect(logger).to have_received(:error).with('Message batch too large, deleting...')
428
+ expect(logger).to have_received(:error).with(
429
+ [
430
+ { key: '1', payload: 'payload-decoded' },
431
+ { key: '2', payload: 'payload-decoded' },
432
+ { key: '3', payload: 'payload-decoded' },
433
+ { key: '4', payload: 'payload-decoded' }
434
+ ]
435
+ )
436
+ end
437
+
438
+ context 'with exception on error logging attempt' do
439
+ let(:message_producer) do
440
+ Deimos::ActiveRecordProducer.topic('my-topic')
441
+ Deimos::ActiveRecordProducer
442
+ end
443
+
444
+ it 'should notify on buffer overflow disregarding decoding exception' do
445
+ subscriber = Deimos.subscribe('db_producer.produce') do |event|
446
+ expect(event.payload[:exception_object].message).to eq('Kafka::BufferOverflow')
447
+ expect(event.payload[:messages]).to eq(messages)
448
+ end
449
+ producer.process_topic('my-topic')
450
+ Deimos.unsubscribe(subscriber)
451
+ expect(logger).to have_received(:error).with('Message batch too large, deleting...')
452
+ expect(logger).to have_received(:error).with(
453
+ 'Large message details logging failure: '\
454
+ 'No key config given - if you are not decoding keys, please use `key_config plain: true`'
455
+ )
456
+ end
457
+ end
458
+ end
391
459
  end
392
460
 
393
461
  describe '#send_pending_metrics' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deimos-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.22.4
4
+ version: 1.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-05 00:00:00.000000000 Z
11
+ date: 2024-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro_turf
@@ -579,6 +579,7 @@ files:
579
579
  - spec/schemas/my_namespace/my_schema_with_date_time.rb
580
580
  - spec/schemas/my_namespace/my_schema_with_id.rb
581
581
  - spec/schemas/my_namespace/my_schema_with_unique_id.rb
582
+ - spec/schemas/my_namespace/my_updated_schema.rb
582
583
  - spec/schemas/my_namespace/wibble.rb
583
584
  - spec/schemas/my_namespace/widget.rb
584
585
  - spec/schemas/my_namespace/widget_the_second.rb
@@ -632,7 +633,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
632
633
  - !ruby/object:Gem::Version
633
634
  version: '0'
634
635
  requirements: []
635
- rubygems_version: 3.3.20
636
+ rubygems_version: 3.1.2
636
637
  signing_key:
637
638
  specification_version: 4
638
639
  summary: Kafka libraries for Ruby.
@@ -706,6 +707,7 @@ test_files:
706
707
  - spec/schemas/my_namespace/my_schema_with_date_time.rb
707
708
  - spec/schemas/my_namespace/my_schema_with_id.rb
708
709
  - spec/schemas/my_namespace/my_schema_with_unique_id.rb
710
+ - spec/schemas/my_namespace/my_updated_schema.rb
709
711
  - spec/schemas/my_namespace/wibble.rb
710
712
  - spec/schemas/my_namespace/widget.rb
711
713
  - spec/schemas/my_namespace/widget_the_second.rb