deimos-ruby 1.23.1.pre.beta6 → 1.23.3

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: ea07999ebe98551b3c7385d81762e9ece4515cfb48391eff869cb866762168a0
4
- data.tar.gz: c36e82b2c8ade6b661d4626904495742dfe2f79b31d7f9bd1c544b9da7808f4c
3
+ metadata.gz: 42d51126a6bf86b0aa338798c9b9a4b479154eda722394940df0bbc8a23e3947
4
+ data.tar.gz: 8d6c27244277078ea3b5d2a23440071aba43db3938c43cbbfe4fef27db207556
5
5
  SHA512:
6
- metadata.gz: 5f4776b1a3e8bc229e1c772d0cba605f25614d8ef2eb633bd8a726e0e8717ec35dcabd84e6079dde466dfe01267a1107d6ee5ed401b6cb60b05424486e3cb18c
7
- data.tar.gz: d525504e4e188f13713fac265df69d011f64f4b4cbd1f01bf8508c047632b2b010cc5277ee928fbc5daed1e01849adf5fe3000166bbefabb730e7db8a3b80b2c
6
+ metadata.gz: 86d98c4e4cc84a380b69196c4d04c51a6a8aaaa05601e2d7deac536495d7c689c987555e23e1bcafb895dc78e24492c9c0b174ee273c0859c9d76795a510d154
7
+ data.tar.gz: 8e7875b92bb043c95721a9a12747f6f6727bc225f1802f5d6a6ba34ee4757884347aaa42b3050d9b77f668b7ebd2654aa322cd46dea3c426d140a191c19f7fb0
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## UNRELEASED
9
9
 
10
+ # 1.23.3 - 2024-01-25
11
+ - Feature: Add configuration to skip messages that are too large to publish via DB poller.
12
+
13
+ # 1.23.2 - 2024-01-22
14
+ - Fix: Send a `publish_error` metric for errors other than `DeliveryFailed`.
15
+
10
16
  # 1.23.0 - 2024-01-09
11
17
 
12
18
  - Fix: Fixed handler metric for status:received, status:success in batch consumption
@@ -500,6 +500,9 @@ module Deimos # rubocop:disable Metrics/ModuleLength
500
500
  # The number of times to retry production when encountering a *non-Kafka* error. Set to nil
501
501
  # for infinite retries.
502
502
  setting :retries, 1
503
+ # If true, rather than shutting down when finding a message that is too large, log an
504
+ # error and skip it.
505
+ setting :skip_too_large_messages, false
503
506
  # Amount of time, in seconds, to wait before catching updates, to allow transactions
504
507
  # to complete but still pick up the right records. Should only be set for time-based mode.
505
508
  setting :delay_time, 2
@@ -43,40 +43,43 @@ module Deimos
43
43
 
44
44
  # This module listens to events published by RubyKafka.
45
45
  module KafkaListener
46
+ # @param exception [Exception]
47
+ def self.handle_exception_with_messages(exception)
48
+ messages = exception.failed_messages
49
+ messages.group_by(&:topic).each do |topic, batch|
50
+ producer = Deimos::Producer.descendants.find { |c| c.topic == topic }
51
+ next if batch.empty? || !producer
52
+
53
+ decoder = Deimos.schema_backend(schema: producer.config[:schema],
54
+ namespace: producer.config[:namespace])
55
+ payloads = batch.map { |m| decoder.decode(m.value) }
56
+
57
+ Deimos.config.metrics&.increment(
58
+ 'publish_error',
59
+ tags: %W(topic:#{topic}),
60
+ by: payloads.size
61
+ )
62
+ Deimos.instrument(
63
+ 'produce_error',
64
+ producer: producer,
65
+ topic: topic,
66
+ exception_object: exception,
67
+ payloads: payloads
68
+ )
69
+ end
70
+ end
71
+
46
72
  # Listens for any exceptions that happen during publishing and re-publishes
47
73
  # as a Deimos event.
48
74
  # @param event [ActiveSupport::Notifications::Event]
49
75
  # @return [void]
50
76
  def self.send_produce_error(event)
51
77
  exception = event.payload[:exception_object]
52
- Rails.logger.info("Exception: #{exception}")
53
78
  return unless exception
54
79
 
55
80
  if exception.respond_to?(:failed_messages)
56
- messages = exception.failed_messages
57
- messages.group_by(&:topic).each do |topic, batch|
58
- producer = Deimos::Producer.descendants.find { |c| c.topic == topic }
59
- next if batch.empty? || !producer
60
-
61
- decoder = Deimos.schema_backend(schema: producer.config[:schema],
62
- namespace: producer.config[:namespace])
63
- payloads = batch.map { |m| decoder.decode(m.value) }
64
-
65
- Deimos.config.metrics&.increment(
66
- 'publish_error',
67
- tags: %W(topic:#{topic}),
68
- by: payloads.size
69
- )
70
- Deimos.instrument(
71
- 'produce_error',
72
- producer: producer,
73
- topic: topic,
74
- exception_object: exception,
75
- payloads: payloads
76
- )
77
- end
81
+ handle_exception_with_messages(exception)
78
82
  else
79
- Rails.logger.info(Deimos.config.metrics)
80
83
  Deimos.config.metrics&.increment(
81
84
  'publish_error',
82
85
  by: event.payload[:message_count] || 1
@@ -87,7 +90,6 @@ module Deimos
87
90
 
88
91
  ActiveSupport::Notifications.subscribe('deliver_messages.producer.kafka') do |*args|
89
92
  event = ActiveSupport::Notifications::Event.new(*args)
90
- Rails.logger.info(event.payload)
91
93
  KafkaListener.send_produce_error(event)
92
94
  end
93
95
  end
@@ -14,7 +14,6 @@ module Deimos
14
14
  raise 'Metrics config must specify namespace' if config[:namespace].nil?
15
15
 
16
16
  logger.info("DatadogMetricsProvider configured with: #{config}")
17
-
18
17
  @client = ::Datadog::Statsd.new(
19
18
  config[:host_ip],
20
19
  config[:host_port],
@@ -25,7 +24,6 @@ module Deimos
25
24
 
26
25
  # :nodoc:
27
26
  def increment(metric_name, options={})
28
- Rails.logger.info("Incrementing #{metric_name} #{options}")
29
27
  @client.increment(metric_name, options)
30
28
  end
31
29
 
@@ -105,6 +105,25 @@ module Deimos
105
105
  raise Deimos::MissingImplementationError
106
106
  end
107
107
 
108
+ # @param exception [Exception]
109
+ # @param batch [Array<ActiveRecord::Base>]
110
+ # @param status [PollStatus]
111
+ # @param span [Object]
112
+ # @return [Boolean]
113
+ def handle_message_too_large(exception, batch, status, span)
114
+ Deimos.config.logger.error("Error publishing through DB Poller: #{exception.message}")
115
+ if @config.skip_too_large_messages
116
+ Deimos.config.logger.error("Skipping messages #{batch.map(&:id).join(', ')} since they are too large")
117
+ Deimos.config.tracer&.set_error(span, exception)
118
+ status.batches_errored += 1
119
+ true
120
+ else # do the same thing as regular Kafka::Error
121
+ sleep(0.5)
122
+ false
123
+ end
124
+ end
125
+
126
+ # rubocop:disable Metrics/AbcSize
108
127
  # @param batch [Array<ActiveRecord::Base>]
109
128
  # @param status [PollStatus]
110
129
  # @return [Boolean]
@@ -118,6 +137,9 @@ module Deimos
118
137
  process_batch(batch)
119
138
  Deimos.config.tracer&.finish(span)
120
139
  status.batches_processed += 1
140
+ rescue Kafka::BufferOverflow, Kafka::MessageSizeTooLarge,
141
+ Kafka::RecordListTooLarge => e
142
+ retry unless handle_message_too_large(e, batch, status, span)
121
143
  rescue Kafka::Error => e # keep trying till it fixes itself
122
144
  Deimos.config.logger.error("Error publishing through DB Poller: #{e.message}")
123
145
  sleep(0.5)
@@ -139,6 +161,7 @@ module Deimos
139
161
  end
140
162
  true
141
163
  end
164
+ # rubocop:enable Metrics/AbcSize
142
165
 
143
166
  # Publish batch using the configured producers
144
167
  # @param batch [Array<ActiveRecord::Base>]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Deimos
4
- VERSION = '1.23.1-beta6'
4
+ VERSION = '1.23.3'
5
5
  end
@@ -191,6 +191,48 @@ each_db_config(Deimos::Utils::DbPoller::Base) do
191
191
  expect(Deimos.config.tracer).to have_received(:finish).with('a span')
192
192
  end
193
193
 
194
+ context 'with skip_too_large_messages on' do
195
+ before(:each) { config.skip_too_large_messages = true }
196
+
197
+ it 'should skip and move on' do
198
+ error = Kafka::MessageSizeTooLarge.new('OH NOES')
199
+ allow(poller).to receive(:sleep)
200
+ allow(poller).to receive(:process_batch) do
201
+ raise error
202
+ end
203
+ poller.retrieve_poll_info
204
+ poller.process_batch_with_span(widgets, status)
205
+ expect(poller).not_to have_received(:sleep)
206
+ expect(Deimos.config.tracer).to have_received(:set_error).with('a span', error)
207
+ expect(status.batches_errored).to eq(1)
208
+ expect(status.batches_processed).to eq(0)
209
+ expect(status.messages_processed).to eq(3)
210
+
211
+ end
212
+ end
213
+
214
+ context 'with skip_too_large_messages off' do
215
+ it 'should retry forever' do
216
+ called_once = false
217
+ allow(poller).to receive(:sleep)
218
+ allow(poller).to receive(:process_batch) do
219
+ unless called_once
220
+ called_once = true
221
+ raise Kafka::MessageSizeTooLarge, 'OH NOES'
222
+ end
223
+ end
224
+ poller.retrieve_poll_info
225
+ poller.process_batch_with_span(widgets, status)
226
+ expect(poller).to have_received(:sleep).once.with(0.5)
227
+ expect(Deimos.config.tracer).to have_received(:finish).with('a span')
228
+ expect(status.batches_errored).to eq(0)
229
+ expect(status.batches_processed).to eq(1)
230
+ expect(status.messages_processed).to eq(3)
231
+
232
+ end
233
+
234
+ end
235
+
194
236
  it 'should retry on Kafka error' do
195
237
  called_once = false
196
238
  allow(poller).to receive(:sleep)
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.23.1.pre.beta6
4
+ version: 1.23.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Orner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-22 00:00:00.000000000 Z
11
+ date: 2024-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: avro_turf
@@ -629,9 +629,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
629
629
  version: '0'
630
630
  required_rubygems_version: !ruby/object:Gem::Requirement
631
631
  requirements:
632
- - - ">"
632
+ - - ">="
633
633
  - !ruby/object:Gem::Version
634
- version: 1.3.1
634
+ version: '0'
635
635
  requirements: []
636
636
  rubygems_version: 3.1.2
637
637
  signing_key: