deimos-ruby 1.22.4 → 1.22.5

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: 8204d945b6997589a67a4c8df92ad9d6b5a6d626d16ac7425e640e0f0b30e8f4
4
- data.tar.gz: 364be699486b78896319d4a79cb61288b25cf0ac35078fa263b75547db19d68e
3
+ metadata.gz: 997678ce4ed796037a0f554a7d0897a9ab58f810f437573da7684a6c23fa5d40
4
+ data.tar.gz: e13fc14fb0bf985a02c38ff628a527198aa1e3bbf1eaab52510ea63832a03f37
5
5
  SHA512:
6
- metadata.gz: ff2f512454da6f4ac478e793ff228e35fac87e7a3c1b58431b6e137672d57014f1ae5dc7cb2d46515481137e9a6ac0a4549950925d802023a224e74b4a1b4d82
7
- data.tar.gz: 73551186d75d2192c0e13dee3647516ae4315fabc42ab73cd27c2c550d7e7fc759ca8897b8e988e5f608d1915097c3c27f69092a002e8b93cf967bf374c2b4ba
6
+ metadata.gz: 90062c59b953e4fff9b1f5ddb0c5107e08f98028a7e221c78637bd9cb57c8d13c081a7417dedad57274e4b2df470a58d31ed5a1a1fd985f853ecca9ab53527fc
7
+ data.tar.gz: fa07d49754b91fdfc48fd6edb46a1906f057ddbd9d0b11d0a66d14382ae1907a0ff7fbd2526e4653e6fc74ed53e78db78203fc043621111193fca370e50da777
data/CHANGELOG.md CHANGED
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 1.22.5 - 2023-07-18
11
+ - Fix: Fixed buffer overflow crash with DB producer.
12
+
10
13
  # 1.22.4 - 2023-07-05
11
14
  - Feature: Add support for message headers.
12
15
 
@@ -39,11 +39,12 @@ module Deimos
39
39
  def self.decoded(messages=[])
40
40
  return [] if messages.empty?
41
41
 
42
- decoder = self.decoder(messages.first.topic)&.new
42
+ decoder_class = self.decoder(messages.first.topic)
43
+ decoder = decoder_class&.new
43
44
  messages.map do |m|
44
45
  {
45
46
  key: m.key.present? ? decoder&.decode_key(m.key) || m.key : nil,
46
- payload: decoder&.decoder&.decode(m.message) || m.message
47
+ payload: decoder_class&.decoder&.decode(m.message) || m.message
47
48
  }
48
49
  end
49
50
  end
@@ -97,11 +97,16 @@ module Deimos
97
97
  Deimos.instrument('db_producer.produce', topic: @current_topic, messages: compacted_messages) do
98
98
  begin
99
99
  produce_messages(compacted_messages.map(&:phobos_message))
100
- rescue Kafka::BufferOverflow, Kafka::MessageSizeTooLarge, Kafka::RecordListTooLarge
100
+ rescue Kafka::BufferOverflow, Kafka::MessageSizeTooLarge, Kafka::RecordListTooLarge => e
101
101
  delete_messages(messages)
102
102
  @logger.error('Message batch too large, deleting...')
103
- @logger.error(Deimos::KafkaMessage.decoded(messages))
104
- raise
103
+ begin
104
+ @logger.error(Deimos::KafkaMessage.decoded(messages))
105
+ rescue StandardError => logging_exception # rubocop:disable Naming/RescuedExceptionsVariableName
106
+ @logger.error("Large message details logging failure: #{logging_exception.message}")
107
+ ensure
108
+ raise e
109
+ end
105
110
  end
106
111
  end
107
112
  delete_messages(messages)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '1.22.4'
4
+ VERSION = '1.22.5'
5
5
  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.22.5
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: 2023-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro_turf