deimos-ruby 2.1.8 → 2.1.9
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/CHANGELOG.md +4 -0
- data/lib/deimos/kafka_source.rb +17 -12
- data/lib/deimos/version.rb +1 -1
- data/spec/kafka_source_spec.rb +44 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52b13a01b0356e08ceb56ae75eb55f39d6578070085184521e063d7fb3714f1f
|
4
|
+
data.tar.gz: 36f972a37d52c3c8fb3ea5e53c21c1f39caad58fa8411f0dc380b5a8b7f1ed9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e5d2c15d11756bc133f1ea57e9c112023c557aa6200a4ac7469f9b07f23835d16593ae6ef9d4e20c76dcb4a6acff9d4723355e14ec6e28d1887e09958a6f3283
|
7
|
+
data.tar.gz: d9f1e82068b7f5c7424590fda13a4d59fa9345dc3841c9b1f8413248f031548b276fa5660d39c9fe4f5621bc47089049f70af97d207e3f02af5122d3971c10a9
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## UNRELEASED
|
9
9
|
|
10
|
+
# 2.1.9 - 2025-08-13
|
11
|
+
|
12
|
+
- Fix: When a model uses multiple producers, `send_kafka_event_on_update` no longer aggregates `watched_attributes` across all producers and publishes to all of them if any field changed. It now evaluates each producer’s `watched_attributes` independently and publishes only to the producers whose fields changed (per‑producer isolation).
|
13
|
+
|
10
14
|
# 2.1.8 - 2025-08-11
|
11
15
|
|
12
16
|
- Feature: Producers can now customize the deletion payload, so different producers using the same model can send different delete messages.
|
data/lib/deimos/kafka_source.rb
CHANGED
@@ -27,18 +27,21 @@ module Deimos
|
|
27
27
|
def send_kafka_event_on_update
|
28
28
|
return unless self.class.kafka_config[:update]
|
29
29
|
|
30
|
-
producers = self.class.kafka_producers
|
31
|
-
fields = producers.flat_map { |p| p.watched_attributes(self) }.uniq
|
32
|
-
fields -= ['updated_at']
|
33
|
-
# Only send an event if a field we care about was changed.
|
34
|
-
any_changes = fields.any? do |field|
|
35
|
-
field_change = self.previous_changes[field]
|
36
|
-
field_change.present? && field_change[0] != field_change[1]
|
37
|
-
end
|
38
|
-
return unless any_changes
|
39
30
|
self.truncate_columns if Deimos.config.producers.truncate_columns
|
40
31
|
|
41
|
-
producers
|
32
|
+
producers = self.class.kafka_producers
|
33
|
+
producers.each do |producer|
|
34
|
+
fields = producer.watched_attributes(self)
|
35
|
+
fields -= ['updated_at']
|
36
|
+
# Only send an event if a field we care about was changed.
|
37
|
+
any_changes = fields.any? do |field|
|
38
|
+
field_change = self.previous_changes[field]
|
39
|
+
field_change.present? && field_change[0] != field_change[1]
|
40
|
+
end
|
41
|
+
next unless any_changes
|
42
|
+
|
43
|
+
producer.send_event(self)
|
44
|
+
end
|
42
45
|
end
|
43
46
|
|
44
47
|
# Send a deletion (null payload) event to Kafka.
|
@@ -82,7 +85,7 @@ module Deimos
|
|
82
85
|
# @!visibility private
|
83
86
|
def import_without_validations_or_callbacks(column_names,
|
84
87
|
array_of_attributes,
|
85
|
-
options={})
|
88
|
+
options = {})
|
86
89
|
results = super
|
87
90
|
if !self.kafka_config[:import] || array_of_attributes.empty?
|
88
91
|
return results
|
@@ -112,7 +115,8 @@ module Deimos
|
|
112
115
|
last_id = if self.connection.adapter_name.downcase =~ /sqlite/
|
113
116
|
self.connection.select_value('select last_insert_rowid()') -
|
114
117
|
hashes_without_id.size + 1
|
115
|
-
else
|
118
|
+
else
|
119
|
+
# mysql
|
116
120
|
self.connection.select_value('select LAST_INSERT_ID()')
|
117
121
|
end
|
118
122
|
hashes_without_id.each_with_index do |attrs, i|
|
@@ -130,6 +134,7 @@ module Deimos
|
|
130
134
|
self.class.columns.each do |col|
|
131
135
|
next unless col.type == :string
|
132
136
|
next if self[col.name].blank?
|
137
|
+
|
133
138
|
if self[col.name].to_s.length > col.limit
|
134
139
|
self[col.name] = self[col.name][0..col.limit - 1]
|
135
140
|
end
|
data/lib/deimos/version.rb
CHANGED
data/spec/kafka_source_spec.rb
CHANGED
@@ -17,10 +17,16 @@ module KafkaSourceSpec
|
|
17
17
|
|
18
18
|
# Dummy producer which mimicks the behavior of a real producer
|
19
19
|
class WidgetProducer < Deimos::ActiveRecordProducer
|
20
|
+
def self.watched_attributes(_record)
|
21
|
+
%w(name widget_id)
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
# Dummy producer which mimicks the behavior of a real producer
|
23
26
|
class WidgetProducerTheSecond < Deimos::ActiveRecordProducer
|
27
|
+
def self.watched_attributes(_record)
|
28
|
+
%w(description widget_id)
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
32
|
# Dummy class we can include the mixin in. Has a backing table created
|
@@ -122,7 +128,6 @@ module KafkaSourceSpec
|
|
122
128
|
def generate_payload(attributes, record)
|
123
129
|
payload = super(attributes, record)
|
124
130
|
payload.merge('id' => record.model_id)
|
125
|
-
|
126
131
|
end
|
127
132
|
|
128
133
|
def generate_deletion_payload(record)
|
@@ -182,6 +187,7 @@ module KafkaSourceSpec
|
|
182
187
|
before(:each) do
|
183
188
|
Deimos.config.producers.truncate_columns = false
|
184
189
|
end
|
190
|
+
|
185
191
|
it 'should not truncate values' do
|
186
192
|
widget = Widget.create!(widget_id: 1, name: 'a' * 500)
|
187
193
|
expect('my-topic').to have_sent({
|
@@ -206,6 +212,7 @@ module KafkaSourceSpec
|
|
206
212
|
before(:each) do
|
207
213
|
Deimos.config.producers.truncate_columns = true
|
208
214
|
end
|
215
|
+
|
209
216
|
it 'should truncate values' do
|
210
217
|
widget = Widget.create!(widget_id: 1, name: 'a' * 500)
|
211
218
|
expect('my-topic').to have_sent({
|
@@ -466,5 +473,41 @@ module KafkaSourceSpec
|
|
466
473
|
}.to raise_error(Deimos::MissingImplementationError)
|
467
474
|
end
|
468
475
|
end
|
476
|
+
|
477
|
+
describe 'Isolated watched‑attribute per producer when send_kafka_event_on_update' do
|
478
|
+
it 'should only send events to producers that watch the name field' do
|
479
|
+
widget = Widget.create!(widget_id: 1, name: 'initial', description: 'initial desc')
|
480
|
+
clear_kafka_messages!
|
481
|
+
|
482
|
+
widget.update_attribute(:name, 'updated name')
|
483
|
+
|
484
|
+
expect('my-topic').to have_sent(hash_including(name: 'updated name'))
|
485
|
+
expect('my-topic-the-second').not_to have_sent(anything)
|
486
|
+
end
|
487
|
+
|
488
|
+
it 'should only send events to producers that watch the description field' do
|
489
|
+
widget = Widget.create!(widget_id: 1, name: 'test', description: 'initial desc')
|
490
|
+
clear_kafka_messages!
|
491
|
+
|
492
|
+
widget.update_attribute(:description, 'updated description')
|
493
|
+
|
494
|
+
expect('my-topic-the-second').to have_sent(anything)
|
495
|
+
expect('my-topic').not_to have_sent(anything)
|
496
|
+
end
|
497
|
+
|
498
|
+
it 'should send events to all producers when a commonly watched field changes' do
|
499
|
+
allow(WidgetProducer).to receive(:watched_attributes).and_return(%w(name widget_id))
|
500
|
+
allow(WidgetProducerTheSecond).to receive(:watched_attributes).and_return(%w(description widget_id))
|
501
|
+
|
502
|
+
widget = Widget.create!(widget_id: 1, name: 'test', description: 'test desc')
|
503
|
+
clear_kafka_messages!
|
504
|
+
|
505
|
+
widget.update_attribute(:widget_id, 999)
|
506
|
+
|
507
|
+
expect('my-topic').to have_sent(hash_including(widget_id: 999))
|
508
|
+
expect('my-topic-the-second').to have_sent(hash_including(widget_id: 999))
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
469
512
|
end
|
470
513
|
end
|
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: 2.1.
|
4
|
+
version: 2.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-08-
|
11
|
+
date: 2025-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: avro_turf
|