dionysus-rb 0.5.0 → 1.0.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 +4 -4
- data/.circleci/config.yml +1 -1
- data/.github/workflows/ci.yml +29 -26
- data/.rubocop.yml +18 -3
- data/.rubocop_todo.yml +14 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +40 -0
- data/Gemfile.lock +66 -50
- data/README.md +51 -2
- data/dionysus-rb.gemspec +3 -3
- data/lib/dionysus/consumer/batch_events_publisher.rb +1 -1
- data/lib/dionysus/consumer/params_batch_processor.rb +4 -4
- data/lib/dionysus/consumer/persistor.rb +2 -2
- data/lib/dionysus/consumer/registry.rb +4 -4
- data/lib/dionysus/consumer/synchronizable_model.rb +1 -1
- data/lib/dionysus/consumer.rb +2 -2
- data/lib/dionysus/producer/base_responder.rb +1 -1
- data/lib/dionysus/producer/outbox/datadog_tracer.rb +12 -1
- data/lib/dionysus/producer/outbox/model.rb +1 -1
- data/lib/dionysus/producer/outbox/publishable.rb +1 -2
- data/lib/dionysus/producer/outbox/publisher.rb +23 -6
- data/lib/dionysus/producer/registry.rb +6 -6
- data/lib/dionysus/producer.rb +2 -2
- data/lib/dionysus/utils/null_instrumenter.rb +2 -0
- data/lib/dionysus/version.rb +1 -1
- data/lib/dionysus.rb +7 -5
- metadata +8 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c0362ffd0074956ac7ace1f3c4a392eaa7b5b09a79ecf113a14f9da8f9f5b22
|
|
4
|
+
data.tar.gz: 44cdab85d128017c09dc0535c1225d9d68515addc5c2d1d4b28b50dbb2fc0150
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 63905f2eb238cdca13e750e728498449d6238be26f30bbe68c4709c61218c989d33dd8c7da553c4c4ec6e36dc6b05cc84a8cc44067048752b88018338d1809ee
|
|
7
|
+
data.tar.gz: cabf8edf52bd2ba5ffaf26608110a7f110ba4a7c15ff2ead082c74cd780c5018bd92b0b44a15e847edcf65c39a898bdd537f2c9c85c3c191c1a1803c1a657e96
|
data/.circleci/config.yml
CHANGED
|
@@ -4,7 +4,7 @@ jobs:
|
|
|
4
4
|
working_directory: ~/BookingSync/dionysus-rb
|
|
5
5
|
parallelism: 1
|
|
6
6
|
docker:
|
|
7
|
-
- image: cimg/ruby:
|
|
7
|
+
- image: cimg/ruby:3.3.11
|
|
8
8
|
environment:
|
|
9
9
|
POSTGRES_URL: "postgres://docker:docker@127.0.0.1:5432"
|
|
10
10
|
DATABASE_URL: "postgres://docker:docker@127.0.0.1:5432/circle_test"
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -6,10 +6,10 @@ jobs:
|
|
|
6
6
|
fail-fast: true
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
8
|
steps:
|
|
9
|
-
- uses: actions/checkout@
|
|
9
|
+
- uses: actions/checkout@v4
|
|
10
10
|
- uses: ruby/setup-ruby@v1
|
|
11
11
|
with:
|
|
12
|
-
ruby-version:
|
|
12
|
+
ruby-version: '3.3'
|
|
13
13
|
bundler-cache: true
|
|
14
14
|
- run: bundle exec rubocop
|
|
15
15
|
rspec:
|
|
@@ -17,7 +17,7 @@ jobs:
|
|
|
17
17
|
strategy:
|
|
18
18
|
fail-fast: false
|
|
19
19
|
matrix:
|
|
20
|
-
ruby: ['
|
|
20
|
+
ruby: ['3.3', '3.4']
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
env:
|
|
23
23
|
DD_PROFILING_NO_EXTENSION: true
|
|
@@ -27,23 +27,6 @@ jobs:
|
|
|
27
27
|
POSTGRES_USER: postgres
|
|
28
28
|
POSTGRES_PASSWORD: postgres
|
|
29
29
|
POSTGRES_DB: dionysus-rb-test
|
|
30
|
-
CLUSTER_ID: kafka-docker-cluster-1
|
|
31
|
-
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
|
32
|
-
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
33
|
-
KAFKA_PROCESS_ROLES: broker,controller
|
|
34
|
-
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
35
|
-
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
|
|
36
|
-
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
|
37
|
-
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://127.0.0.1:9092
|
|
38
|
-
KAFKA_BROKER_ID: 1
|
|
39
|
-
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@127.0.0.1:9093
|
|
40
|
-
ALLOW_PLAINTEXT_LISTENER: 'yes'
|
|
41
|
-
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
|
|
42
|
-
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
|
43
|
-
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
|
44
|
-
KAFKA_ALLOW_EVERYONE_IF_NO_ACL_FOUND: "true"
|
|
45
|
-
KAFKA_AUTHORIZER_CLASS_NAME: org.apache.kafka.metadata.authorizer.StandardAuthorizer
|
|
46
|
-
KAFKA_CREATE_TOPICS: "v102_rentals:1:1"
|
|
47
30
|
services:
|
|
48
31
|
postgres:
|
|
49
32
|
image: postgres:14
|
|
@@ -63,14 +46,34 @@ jobs:
|
|
|
63
46
|
--health-interval 10s
|
|
64
47
|
--health-timeout 5s
|
|
65
48
|
--health-retries 5
|
|
49
|
+
kafka:
|
|
50
|
+
image: confluentinc/cp-kafka:7.5.2
|
|
51
|
+
env:
|
|
52
|
+
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
|
|
53
|
+
KAFKA_NODE_ID: 1
|
|
54
|
+
KAFKA_PROCESS_ROLES: broker,controller
|
|
55
|
+
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093
|
|
56
|
+
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
|
|
57
|
+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
|
|
58
|
+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
|
|
59
|
+
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
|
60
|
+
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
61
|
+
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
|
|
62
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
|
|
63
|
+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
|
|
64
|
+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
|
|
65
|
+
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
|
|
66
|
+
ports:
|
|
67
|
+
- 9092:9092
|
|
68
|
+
options: >-
|
|
69
|
+
--health-cmd "kafka-topics --bootstrap-server localhost:9092 --list"
|
|
70
|
+
--health-interval 10s
|
|
71
|
+
--health-timeout 10s
|
|
72
|
+
--health-retries 12
|
|
73
|
+
--health-start-period 20s
|
|
66
74
|
steps:
|
|
67
|
-
- uses: actions/checkout@
|
|
68
|
-
- name: Start Kafka with docker-compose
|
|
69
|
-
run: |
|
|
70
|
-
docker-compose up -d || (sleep 5 && docker-compose up -d)
|
|
71
|
-
|
|
75
|
+
- uses: actions/checkout@v4
|
|
72
76
|
- uses: ruby/setup-ruby@v1
|
|
73
|
-
|
|
74
77
|
with:
|
|
75
78
|
ruby-version: ${{ matrix.ruby }}
|
|
76
79
|
bundler-cache: true
|
data/.rubocop.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
plugins:
|
|
4
4
|
- rubocop-performance
|
|
5
5
|
- rubocop-rspec
|
|
6
6
|
- rubocop-rake
|
|
@@ -11,7 +11,7 @@ inherit_mode:
|
|
|
11
11
|
|
|
12
12
|
AllCops:
|
|
13
13
|
NewCops: enable
|
|
14
|
-
TargetRubyVersion:
|
|
14
|
+
TargetRubyVersion: 3.3
|
|
15
15
|
Exclude:
|
|
16
16
|
- "db/**/*"
|
|
17
17
|
- "bin/**/*"
|
|
@@ -129,6 +129,21 @@ RSpec/ExampleLength:
|
|
|
129
129
|
Naming/VariableNumber:
|
|
130
130
|
Enabled: false
|
|
131
131
|
|
|
132
|
+
# Same rationale as Naming/VariableNumber: the specs deliberately number fixtures
|
|
133
|
+
# (rental_1, metadata_2) when they describe an ordered batch.
|
|
134
|
+
RSpec/IndexedLet:
|
|
135
|
+
Enabled: false
|
|
136
|
+
|
|
137
|
+
# Development dependencies are declared in the gemspec, not in the Gemfile.
|
|
138
|
+
Gemspec/DevelopmentDependencies:
|
|
139
|
+
Enabled: false
|
|
140
|
+
|
|
141
|
+
# `is_expected_block` (spec/support/is_expected_block.rb) is `expect { subject }`,
|
|
142
|
+
# which the cop cannot see through.
|
|
143
|
+
RSpec/NoExpectationExample:
|
|
144
|
+
AllowedPatterns:
|
|
145
|
+
- "^is_expected_block"
|
|
146
|
+
|
|
132
147
|
Metrics/BlockLength:
|
|
133
148
|
Max: 30
|
|
134
149
|
Exclude:
|
|
@@ -136,7 +151,7 @@ Metrics/BlockLength:
|
|
|
136
151
|
- 'lib/dionysus/support/rspec/outbox_publishable.rb'
|
|
137
152
|
- 'lib/dionysus/consumer/persistor.rb'
|
|
138
153
|
|
|
139
|
-
Naming/
|
|
154
|
+
Naming/PredicatePrefix:
|
|
140
155
|
Enabled: false
|
|
141
156
|
|
|
142
157
|
Metrics/AbcSize:
|
data/.rubocop_todo.yml
CHANGED
|
@@ -52,3 +52,17 @@ Metrics/CyclomaticComplexity:
|
|
|
52
52
|
Metrics/BlockLength:
|
|
53
53
|
Exclude:
|
|
54
54
|
- 'lib/dionysus/producer/karafka_responder_generator.rb'
|
|
55
|
+
|
|
56
|
+
# `declared_attributes` and friends are Arrays of [name, options] pairs, not Hashes,
|
|
57
|
+
# so the cop's each_key/each_value suggestion raises NoMethodError.
|
|
58
|
+
Style/HashEachMethods:
|
|
59
|
+
Exclude:
|
|
60
|
+
- 'lib/dionysus/producer/model_serializer.rb'
|
|
61
|
+
|
|
62
|
+
# integration_spec prints progress for a long-running Kafka run; the null provider
|
|
63
|
+
# specs use `puts` as the sentinel proving the block was called.
|
|
64
|
+
RSpec/Output:
|
|
65
|
+
Exclude:
|
|
66
|
+
- 'spec/dionysus/utils/null_retry_provider_spec.rb'
|
|
67
|
+
- 'spec/dionysus/utils/null_transaction_provider_spec.rb'
|
|
68
|
+
- 'spec/integration_spec.rb'
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby-3.3.11
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.0.0]
|
|
4
|
+
|
|
5
|
+
Brings `dionysus-rb` back in line with the private gem it was extracted from, which had moved on
|
|
6
|
+
by four releases.
|
|
7
|
+
|
|
8
|
+
### Breaking changes
|
|
9
|
+
|
|
10
|
+
- Require Ruby >= 3.3 (was >= 2.7).
|
|
11
|
+
- Require karafka `~> 2.4` (was `~> 2.0`). Follow https://karafka.io/docs/Upgrades-2.4/ - most
|
|
12
|
+
notably, `Karafka::Messages::Metadata` no longer carries a single `deserializer`, it carries a
|
|
13
|
+
`deserializers` config with separate `payload` and `key` entries, and `key` is now `raw_key`.
|
|
14
|
+
This only affects code that constructs metadata by hand, such as consumer specs.
|
|
15
|
+
- The instrumenter is now expected to respond to `increment(name, options)` in addition to
|
|
16
|
+
`instrument`. `Dionysus::Utils::NullInstrumenter` implements it; a custom instrumenter that does
|
|
17
|
+
not will raise when a publish produces no message (see below).
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Notify when publishing an outbox record produces no Kafka message at all.
|
|
22
|
+
`Dionysus::Producer::Outbox::Publisher#publish` could complete successfully having sent nothing -
|
|
23
|
+
a model declared only as a `with:` dependency has no top-level responder, so when its parent
|
|
24
|
+
could not be resolved the call returned normally - and `RecordsProcessor` then marked the record
|
|
25
|
+
as published, losing the change in every consumer with no error and no retry. Such a record is
|
|
26
|
+
now logged, counted as `dionysus.publish.nothing_published` and reported through the configured
|
|
27
|
+
`error_handler`. It notifies rather than raises: the producer cannot distinguish a legitimately
|
|
28
|
+
deleted parent from one that is not visible yet.
|
|
29
|
+
- `Dionysus.initialize_application!` accepts `consumer_group_name`, which is used verbatim as the
|
|
30
|
+
consumer group name and takes precedence over `consumer_group_prefix`. `consumer_group_prefix`
|
|
31
|
+
stays supported and unchanged, so the documented migration path from `bookingsync-prometheus`
|
|
32
|
+
keeps working.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Compatibility with the `datadog` gem 2.0, which renamed the `span_type:` keyword of
|
|
37
|
+
`Datadog::Tracing#trace` to `type:`. `Dionysus::Producer::Outbox::DatadogTracer` now picks the
|
|
38
|
+
right keyword depending on whether the pre-2.0 `ddtrace` gem is loaded.
|
|
39
|
+
- Do not publish the `dionysus.consume_batch` event when the batch is empty.
|
|
40
|
+
- `Dionysus::Producer::Outbox::Publisher` no longer trips over a `nil` entry in a parent
|
|
41
|
+
association collection.
|
|
42
|
+
|
|
3
43
|
## [0.5.0]
|
|
4
44
|
- Publish consumed messages batch as `dionysus.consume_batch` event.
|
|
5
45
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
dionysus-rb (0.
|
|
4
|
+
dionysus-rb (1.0.0)
|
|
5
5
|
activerecord (>= 5)
|
|
6
6
|
activesupport (>= 3.2)
|
|
7
7
|
concurrent-ruby
|
|
8
8
|
dry-monitor
|
|
9
9
|
file-based-healthcheck
|
|
10
|
-
karafka (~> 2.
|
|
10
|
+
karafka (~> 2.4)
|
|
11
11
|
sidekiq
|
|
12
12
|
sidekiq-cron
|
|
13
13
|
sigurd
|
|
@@ -34,8 +34,8 @@ GEM
|
|
|
34
34
|
mutex_m
|
|
35
35
|
tzinfo (~> 2.0)
|
|
36
36
|
amq-protocol (2.3.2)
|
|
37
|
-
ast (2.4.
|
|
38
|
-
base64 (0.
|
|
37
|
+
ast (2.4.3)
|
|
38
|
+
base64 (0.3.0)
|
|
39
39
|
bigdecimal (3.1.4)
|
|
40
40
|
bunny (2.22.0)
|
|
41
41
|
amq-protocol (~> 2.3, >= 2.3.1)
|
|
@@ -43,20 +43,20 @@ GEM
|
|
|
43
43
|
byebug (11.1.3)
|
|
44
44
|
carrot-top (0.0.7)
|
|
45
45
|
json
|
|
46
|
+
cgi (0.5.2)
|
|
46
47
|
concurrent-ruby (1.2.2)
|
|
47
48
|
connection_pool (2.4.1)
|
|
48
49
|
crypt_keeper (0.13.1)
|
|
49
50
|
activerecord (>= 3.0)
|
|
50
51
|
activesupport (>= 3.0)
|
|
51
|
-
datadog
|
|
52
|
+
datadog (2.40.0)
|
|
53
|
+
cgi
|
|
54
|
+
datadog-ruby_core_source (~> 3.5, >= 3.5.4)
|
|
55
|
+
libdatadog (~> 36.0.0.1.0)
|
|
56
|
+
libddwaf (~> 1.30.0.0.0)
|
|
57
|
+
logger
|
|
52
58
|
msgpack
|
|
53
|
-
|
|
54
|
-
datadog-ci (~> 0.5.0)
|
|
55
|
-
debase-ruby_core_source (= 3.2.3)
|
|
56
|
-
libdatadog (~> 5.0.0.1.0)
|
|
57
|
-
libddwaf (~> 1.14.0.0.0)
|
|
58
|
-
msgpack
|
|
59
|
-
debase-ruby_core_source (3.2.3)
|
|
59
|
+
datadog-ruby_core_source (3.5.4)
|
|
60
60
|
diff-lcs (1.5.0)
|
|
61
61
|
dogstatsd-ruby (5.5.0)
|
|
62
62
|
drb (2.1.1)
|
|
@@ -118,32 +118,41 @@ GEM
|
|
|
118
118
|
i18n (1.14.1)
|
|
119
119
|
concurrent-ruby (~> 1.0)
|
|
120
120
|
ice_nine (0.11.2)
|
|
121
|
-
json (2.
|
|
122
|
-
karafka (2.2
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
json (2.21.2)
|
|
122
|
+
karafka (2.5.2)
|
|
123
|
+
base64 (~> 0.2)
|
|
124
|
+
karafka-core (>= 2.5.6, < 2.6.0)
|
|
125
|
+
karafka-rdkafka (>= 0.22.0)
|
|
126
|
+
waterdrop (>= 2.8.9, < 3.0.0)
|
|
126
127
|
zeitwerk (~> 2.3)
|
|
127
|
-
karafka-core (2.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
karafka-rdkafka (0.
|
|
128
|
+
karafka-core (2.5.13)
|
|
129
|
+
karafka-rdkafka (>= 0.20.0)
|
|
130
|
+
logger (>= 1.6.0)
|
|
131
|
+
karafka-rdkafka (0.22.2)
|
|
131
132
|
ffi (~> 1.15)
|
|
133
|
+
json (> 2.0)
|
|
134
|
+
logger
|
|
132
135
|
mini_portile2 (~> 2.6)
|
|
133
136
|
rake (> 12)
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
language_server-protocol (3.17.0.6)
|
|
138
|
+
libdatadog (36.0.0.1.0)
|
|
139
|
+
libddwaf (1.30.0.0.2)
|
|
136
140
|
ffi (~> 1.0)
|
|
141
|
+
lint_roller (1.1.0)
|
|
142
|
+
logger (1.7.0)
|
|
137
143
|
mini_portile2 (2.8.4)
|
|
138
144
|
minitest (5.20.0)
|
|
139
|
-
msgpack (1.
|
|
145
|
+
msgpack (1.8.4)
|
|
140
146
|
multi_json (1.15.0)
|
|
141
147
|
mutex_m (0.1.2)
|
|
142
|
-
parallel (1.
|
|
143
|
-
parser (3.
|
|
148
|
+
parallel (2.1.0)
|
|
149
|
+
parser (3.3.12.0)
|
|
144
150
|
ast (~> 2.4.1)
|
|
151
|
+
racc
|
|
145
152
|
pg (1.3.5)
|
|
153
|
+
prism (1.9.0)
|
|
146
154
|
raabro (1.4.0)
|
|
155
|
+
racc (1.8.1)
|
|
147
156
|
rack (2.2.4)
|
|
148
157
|
rainbow (3.1.1)
|
|
149
158
|
rake (13.0.6)
|
|
@@ -153,10 +162,9 @@ GEM
|
|
|
153
162
|
redis (>= 3.0.4)
|
|
154
163
|
redlock (1.2.2)
|
|
155
164
|
redis (>= 3.0.0, < 5.0)
|
|
156
|
-
regexp_parser (2.
|
|
165
|
+
regexp_parser (2.12.0)
|
|
157
166
|
request_store (1.5.1)
|
|
158
167
|
rack (>= 1.4)
|
|
159
|
-
rexml (3.2.5)
|
|
160
168
|
rspec (3.12.0)
|
|
161
169
|
rspec-core (~> 3.12.0)
|
|
162
170
|
rspec-expectations (~> 3.12.0)
|
|
@@ -175,26 +183,32 @@ GEM
|
|
|
175
183
|
rspec-core (~> 3.0, >= 3.0.0)
|
|
176
184
|
sidekiq (>= 2.4.0)
|
|
177
185
|
rspec-support (3.12.1)
|
|
178
|
-
rubocop (1.
|
|
186
|
+
rubocop (1.89.0)
|
|
179
187
|
json (~> 2.3)
|
|
180
|
-
|
|
181
|
-
|
|
188
|
+
language_server-protocol (~> 3.17.0.2)
|
|
189
|
+
lint_roller (~> 1.1.0)
|
|
190
|
+
parallel (>= 1.10)
|
|
191
|
+
parser (>= 3.3.0.2)
|
|
182
192
|
rainbow (>= 2.2.2, < 4.0)
|
|
183
|
-
regexp_parser (>=
|
|
184
|
-
|
|
185
|
-
rubocop-ast (>= 1.20.1, < 2.0)
|
|
193
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
194
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
186
195
|
ruby-progressbar (~> 1.7)
|
|
187
|
-
unicode-display_width (>=
|
|
188
|
-
rubocop-ast (1.
|
|
189
|
-
parser (>= 3.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
rubocop (
|
|
195
|
-
rubocop-
|
|
196
|
-
|
|
197
|
-
|
|
196
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
197
|
+
rubocop-ast (1.50.0)
|
|
198
|
+
parser (>= 3.3.7.2)
|
|
199
|
+
prism (~> 1.7)
|
|
200
|
+
rubocop-performance (1.26.1)
|
|
201
|
+
lint_roller (~> 1.1)
|
|
202
|
+
rubocop (>= 1.75.0, < 2.0)
|
|
203
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
204
|
+
rubocop-rake (0.7.1)
|
|
205
|
+
lint_roller (~> 1.1)
|
|
206
|
+
rubocop (>= 1.72.1)
|
|
207
|
+
rubocop-rspec (3.10.2)
|
|
208
|
+
lint_roller (~> 1.1)
|
|
209
|
+
regexp_parser (>= 2.0)
|
|
210
|
+
rubocop (~> 1.86, >= 1.86.2)
|
|
211
|
+
ruby-progressbar (1.13.0)
|
|
198
212
|
ruby2_keywords (0.0.5)
|
|
199
213
|
sentry-ruby (5.4.1)
|
|
200
214
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
@@ -215,14 +229,16 @@ GEM
|
|
|
215
229
|
sorted_set (1.0.3)
|
|
216
230
|
rbtree
|
|
217
231
|
set (~> 1.0)
|
|
218
|
-
thor (1.2.2)
|
|
219
232
|
timecop (0.9.5)
|
|
220
233
|
timeout (0.4.0)
|
|
221
234
|
tzinfo (2.0.6)
|
|
222
235
|
concurrent-ruby (~> 1.0)
|
|
223
|
-
unicode-display_width (
|
|
224
|
-
|
|
225
|
-
|
|
236
|
+
unicode-display_width (3.2.0)
|
|
237
|
+
unicode-emoji (~> 4.1)
|
|
238
|
+
unicode-emoji (4.2.0)
|
|
239
|
+
waterdrop (2.8.13)
|
|
240
|
+
karafka-core (>= 2.4.9, < 3.0.0)
|
|
241
|
+
karafka-rdkafka (>= 0.20.0)
|
|
226
242
|
zeitwerk (~> 2.3)
|
|
227
243
|
zeitwerk (2.6.12)
|
|
228
244
|
|
|
@@ -234,7 +250,7 @@ DEPENDENCIES
|
|
|
234
250
|
bundler
|
|
235
251
|
byebug
|
|
236
252
|
crypt_keeper
|
|
237
|
-
|
|
253
|
+
datadog
|
|
238
254
|
dionysus-rb!
|
|
239
255
|
dogstatsd-ruby
|
|
240
256
|
hermes-rb
|
data/README.md
CHANGED
|
@@ -62,7 +62,19 @@ Dionysus.initialize_application!(
|
|
|
62
62
|
)
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
By default, the name of the consumer
|
|
65
|
+
By default, the name of the consumer group will be `"dionysus_consumer_group_for_NAME_OF_THE_APP"`, where `dionysus_consumer_group_for` is the `consumer_group_prefix`.
|
|
66
|
+
|
|
67
|
+
If a prefix is not enough and you need to control the entire name, provide `consumer_group_name`, which is used verbatim and takes precedence over `consumer_group_prefix`:
|
|
68
|
+
|
|
69
|
+
``` rb
|
|
70
|
+
Dionysus.initialize_application!(
|
|
71
|
+
environment: ENV["RAILS_ENV"],
|
|
72
|
+
seed_brokers: ENV.fetch("DIONYSUS_SEED_BROKER").split(";"),
|
|
73
|
+
client_id: "NAME_OF_THE_APP",
|
|
74
|
+
logger: Rails.logger,
|
|
75
|
+
consumer_group_name: "your_custom_consumer_group_name"
|
|
76
|
+
)
|
|
77
|
+
```
|
|
66
78
|
|
|
67
79
|
|
|
68
80
|
And define `dionysus.rb` initializer with your Kafka topics:
|
|
@@ -234,9 +246,16 @@ class Dionysus::Utils::NullInstrumenter
|
|
|
234
246
|
def self.instrument(name, payload = {})
|
|
235
247
|
yield
|
|
236
248
|
end
|
|
249
|
+
|
|
250
|
+
def self.increment(name, options = {})
|
|
251
|
+
end
|
|
237
252
|
end
|
|
238
253
|
```
|
|
239
254
|
|
|
255
|
+
`increment` is used for counters that are not tied to a block, currently only
|
|
256
|
+
`dionysus.publish.nothing_published` (see the Transactional Outbox Pattern section). A custom
|
|
257
|
+
instrumenter that does not implement it will raise when that counter is emitted.
|
|
258
|
+
|
|
240
259
|
|
|
241
260
|
Event Bus is useful if you want to react to some events, with the following interface ((this is the default class)):
|
|
242
261
|
|
|
@@ -508,6 +527,24 @@ bundle exec outbox_worker_health_check
|
|
|
508
527
|
|
|
509
528
|
It works for both readiness and liveness checks.
|
|
510
529
|
|
|
530
|
+
##### Publishes that produce no Kafka message
|
|
531
|
+
|
|
532
|
+
`Dionysus::Producer::Outbox::Publisher#publish` can legitimately match no responder at all - a
|
|
533
|
+
model declared only as a `with:` dependency has no top-level responder of its own, so when its
|
|
534
|
+
parent cannot be resolved nothing gets sent. The outbox record would still be stamped as
|
|
535
|
+
published, which means the change is silently lost in every consumer.
|
|
536
|
+
|
|
537
|
+
Such a record is now logged via `Dionysus.logger.error`, reported through the configured
|
|
538
|
+
`error_handler` with `capture_message`, and counted as:
|
|
539
|
+
|
|
540
|
+
```
|
|
541
|
+
instrumenter.increment("dionysus.publish.nothing_published", tags: ["resource:<class>", "topic:<topic>"])
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
It notifies rather than raises, because the producer cannot tell a legitimately deleted parent
|
|
545
|
+
from one that is merely not visible yet, and raising on the former would retry forever. Reprocess
|
|
546
|
+
the reported record from the console.
|
|
547
|
+
|
|
511
548
|
#### Tombstoning records
|
|
512
549
|
|
|
513
550
|
The only way to get rid of messages under a given key from Kafka is to tombstone them. Use `Dionysus::Producer::Outbox::TombstonePublisher` to do it:
|
|
@@ -677,7 +714,19 @@ Dionysus.initialize_application!(
|
|
|
677
714
|
)
|
|
678
715
|
```
|
|
679
716
|
|
|
680
|
-
By default, the name of the consumer
|
|
717
|
+
By default, the name of the consumer group will be `"dionysus_consumer_group_for_NAME_OF_THE_APP"`, where `dionysus_consumer_group_for` is the `consumer_group_prefix`.
|
|
718
|
+
|
|
719
|
+
If a prefix is not enough and you need to control the entire name, provide `consumer_group_name`, which is used verbatim and takes precedence over `consumer_group_prefix`:
|
|
720
|
+
|
|
721
|
+
``` rb
|
|
722
|
+
Dionysus.initialize_application!(
|
|
723
|
+
environment: ENV["RAILS_ENV"],
|
|
724
|
+
seed_brokers: ENV.fetch("DIONYSUS_SEED_BROKER").split(";"),
|
|
725
|
+
client_id: "NAME_OF_THE_APP",
|
|
726
|
+
logger: Rails.logger,
|
|
727
|
+
consumer_group_name: "your_custom_consumer_group_name"
|
|
728
|
+
)
|
|
729
|
+
```
|
|
681
730
|
|
|
682
731
|
|
|
683
732
|
And define `dionysus.rb` initializer:
|
data/dionysus-rb.gemspec
CHANGED
|
@@ -30,7 +30,7 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.add_development_dependency "bundler"
|
|
31
31
|
spec.add_development_dependency "byebug"
|
|
32
32
|
spec.add_development_dependency "crypt_keeper"
|
|
33
|
-
spec.add_development_dependency "
|
|
33
|
+
spec.add_development_dependency "datadog"
|
|
34
34
|
spec.add_development_dependency "dogstatsd-ruby"
|
|
35
35
|
spec.add_development_dependency "hermes-rb"
|
|
36
36
|
spec.add_development_dependency "pg"
|
|
@@ -52,13 +52,13 @@ Gem::Specification.new do |spec|
|
|
|
52
52
|
spec.add_dependency "concurrent-ruby"
|
|
53
53
|
spec.add_dependency "dry-monitor"
|
|
54
54
|
spec.add_dependency "file-based-healthcheck"
|
|
55
|
-
spec.add_dependency "karafka", "~> 2.
|
|
55
|
+
spec.add_dependency "karafka", "~> 2.4"
|
|
56
56
|
spec.add_dependency "sidekiq"
|
|
57
57
|
spec.add_dependency "sidekiq-cron"
|
|
58
58
|
spec.add_dependency "sigurd"
|
|
59
59
|
spec.add_dependency "waterdrop", "~> 2.0"
|
|
60
60
|
spec.add_dependency "zeitwerk"
|
|
61
61
|
|
|
62
|
-
spec.required_ruby_version = ">=
|
|
62
|
+
spec.required_ruby_version = ">= 3.3"
|
|
63
63
|
spec.metadata["rubygems_mfa_required"] = "true"
|
|
64
64
|
end
|
|
@@ -30,7 +30,7 @@ class Dionysus::Consumer::BatchEventsPublisher
|
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def publish_events_batch_via_event_bus(events_batch_data)
|
|
33
|
-
config.event_bus.publish("dionysus.consume_batch", events_batch_data)
|
|
33
|
+
config.event_bus.publish("dionysus.consume_batch", events_batch_data) if events_batch_data.any?
|
|
34
34
|
events_batch_data
|
|
35
35
|
end
|
|
36
36
|
|
|
@@ -57,13 +57,13 @@ class Dionysus::Consumer::ParamsBatchProcessor
|
|
|
57
57
|
message_filters.find { |f| f.ignore_message?(topic: topic, message: message, transformed_data: transformed_data) }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
-
def instrument(label, options = {}, &
|
|
61
|
-
config.instrumenter.instrument(label, options, &
|
|
60
|
+
def instrument(label, options = {}, &)
|
|
61
|
+
config.instrumenter.instrument(label, options, &)
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
def with_mutex(metadata, config, &
|
|
64
|
+
def with_mutex(metadata, config, &)
|
|
65
65
|
message_key = metadata.key || SecureRandom.uuid
|
|
66
66
|
config.processing_mutex_provider.send(config.processing_mutex_method_name, "Dionysus-#{message_key}",
|
|
67
|
-
&
|
|
67
|
+
&)
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -151,7 +151,7 @@ class Dionysus::Consumer::Persistor
|
|
|
151
151
|
end
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
def instrument(label, options = {}, &
|
|
155
|
-
config.instrumenter.instrument(label, options, &
|
|
154
|
+
def instrument(label, options = {}, &)
|
|
155
|
+
config.instrumenter.instrument(label, options, &)
|
|
156
156
|
end
|
|
157
157
|
end
|
|
@@ -8,9 +8,9 @@ class Dionysus::Consumer::Registry
|
|
|
8
8
|
@container = {}
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def namespace(namespace, &
|
|
11
|
+
def namespace(namespace, &)
|
|
12
12
|
registration = Registration.new(namespace)
|
|
13
|
-
registration.instance_eval(&
|
|
13
|
+
registration.instance_eval(&)
|
|
14
14
|
container[namespace] = registration
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -32,8 +32,8 @@ class Dionysus::Consumer::Registry
|
|
|
32
32
|
@deserializer_klass = deserializer_klass
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def topic(name, options = {}, &
|
|
36
|
-
new_topic = Topic.new(namespace, name, deserializer_klass, options, &
|
|
35
|
+
def topic(name, options = {}, &)
|
|
36
|
+
new_topic = Topic.new(namespace, name, deserializer_klass, options, &)
|
|
37
37
|
consumer = Dionysus::Consumer::KarafkaConsumerGenerator.new.generate(
|
|
38
38
|
Dionysus::Consumer.configuration, new_topic
|
|
39
39
|
)
|
|
@@ -27,7 +27,7 @@ class Dionysus::Consumer::SynchronizableModel < SimpleDelegator
|
|
|
27
27
|
|
|
28
28
|
def assign_attributes_from_dionysus(attributes)
|
|
29
29
|
public_send("#{synced_data_attribute}=", attributes)
|
|
30
|
-
reverse_mapping = config.attributes_mapping_for_model(model.model_name).to_a.
|
|
30
|
+
reverse_mapping = config.attributes_mapping_for_model(model.model_name).to_a.to_h(&:reverse)
|
|
31
31
|
|
|
32
32
|
assignable_attributes = extract_assignable_attributes(attributes)
|
|
33
33
|
.map { |key, value| apply_mapping(reverse_mapping, key, value) }
|
data/lib/dionysus/consumer.rb
CHANGED
|
@@ -13,9 +13,9 @@ class Dionysus::Consumer
|
|
|
13
13
|
configuration.registry
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def self.declare(&
|
|
16
|
+
def self.declare(&)
|
|
17
17
|
registry = Dionysus::Consumer::Registry.new
|
|
18
|
-
registry.instance_eval(&
|
|
18
|
+
registry.instance_eval(&)
|
|
19
19
|
|
|
20
20
|
Dionysus.inject_routing!(registry)
|
|
21
21
|
|
|
@@ -9,7 +9,8 @@ class Dionysus::Producer::Outbox::DatadogTracer
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def trace(event_name, topic)
|
|
12
|
-
tracer.trace(event_name,
|
|
12
|
+
tracer.trace(event_name, span_type_key => "worker", service: self.class.service_name,
|
|
13
|
+
on_error: error_handler) do |span|
|
|
13
14
|
span.set_tag("topic", topic)
|
|
14
15
|
|
|
15
16
|
yield
|
|
@@ -26,6 +27,16 @@ class Dionysus::Producer::Outbox::DatadogTracer
|
|
|
26
27
|
end
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
# datadog 2.0 renamed the `span_type:` keyword of Datadog::Tracing#trace to `type:`.
|
|
31
|
+
# DDTrace is only defined by the pre-2.0 ddtrace gem.
|
|
32
|
+
def span_type_key
|
|
33
|
+
if defined?(DDTrace)
|
|
34
|
+
:span_type
|
|
35
|
+
else
|
|
36
|
+
:type
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
29
40
|
def error_handler
|
|
30
41
|
->(span, error) { span.set_error(error) }
|
|
31
42
|
end
|
|
@@ -78,7 +78,7 @@ module Dionysus::Producer::Outbox::Model
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def error
|
|
81
|
-
if
|
|
81
|
+
if [1, -1].include?(error_class_arity)
|
|
82
82
|
error_class.constantize.new(error_message)
|
|
83
83
|
else
|
|
84
84
|
StandardError.new("#{error_class_constant}: #{error_message}")
|
|
@@ -74,8 +74,7 @@ class Dionysus::Producer::Outbox::Publishable < SimpleDelegator
|
|
|
74
74
|
.map(&:primary_topic)
|
|
75
75
|
topics_from_dependencies = Dionysus::Producer
|
|
76
76
|
.responders_for_dependency_parent(model.class)
|
|
77
|
-
.map
|
|
78
|
-
.map(&:primary_topic)
|
|
77
|
+
.map { |dependency| dependency.last.primary_topic }
|
|
79
78
|
|
|
80
79
|
[top_level_topics, topics_from_dependencies]
|
|
81
80
|
.flatten
|
|
@@ -33,8 +33,10 @@ class Dionysus::Producer::Outbox::Publisher
|
|
|
33
33
|
return
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
publish_for_top_level_resource(outbox_record, resource, event_name, topic, options)
|
|
37
|
-
|
|
36
|
+
published_count = publish_for_top_level_resource(outbox_record, resource, event_name, topic, options) +
|
|
37
|
+
publish_for_dependency(resource, topic, options)
|
|
38
|
+
handle_nothing_published(resource, event_name, topic) if published_count.zero?
|
|
39
|
+
published_count
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
|
|
@@ -67,19 +69,20 @@ class Dionysus::Producer::Outbox::Publisher
|
|
|
67
69
|
delegate :logger, to: Dionysus
|
|
68
70
|
|
|
69
71
|
def publish_for_top_level_resource(outbox_record, resource, event_name, topic, options)
|
|
70
|
-
Dionysus::Producer.responders_for_model_for_topic(resource.class, topic).
|
|
72
|
+
Dionysus::Producer.responders_for_model_for_topic(resource.class, topic).sum do |responder|
|
|
71
73
|
partition_key = outbox_record.partition_key.presence || Dionysus::Producer::PartitionKey.new(
|
|
72
74
|
resource
|
|
73
75
|
).to_key(responder: responder)
|
|
74
76
|
key = Dionysus::Producer::Key.new(resource).to_key
|
|
75
77
|
|
|
76
78
|
responder.call(generate_message(event_name, resource), options.merge(partition_key: partition_key, key: key))
|
|
79
|
+
1
|
|
77
80
|
end
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
def publish_for_dependency(resource, topic, options)
|
|
81
84
|
Dionysus::Producer.responders_for_dependency_parent_for_topic(resource.class,
|
|
82
|
-
topic).
|
|
85
|
+
topic).sum do |parent_klass, responder|
|
|
83
86
|
parent_event_name = Dionysus::Producer::Outbox::EventName.new(
|
|
84
87
|
parent_klass.model_name.singular
|
|
85
88
|
).updated
|
|
@@ -89,10 +92,11 @@ class Dionysus::Producer::Outbox::Publisher
|
|
|
89
92
|
elsif resource.class.reflect_on_association(parent_klass.model_name.plural)
|
|
90
93
|
parent_records = resource.public_send(parent_klass.model_name.plural)
|
|
91
94
|
else
|
|
92
|
-
next
|
|
95
|
+
next 0
|
|
93
96
|
end
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
parent_records = parent_records.to_a.compact
|
|
99
|
+
example_parent_record = parent_records.first or next 0
|
|
96
100
|
partition_key = Dionysus::Producer::PartitionKey.new(example_parent_record, config: config)
|
|
97
101
|
.to_key(responder: responder)
|
|
98
102
|
key = Dionysus::Producer::Key.new(example_parent_record).to_key
|
|
@@ -101,9 +105,22 @@ class Dionysus::Producer::Outbox::Publisher
|
|
|
101
105
|
responder.call(generate_message(parent_event_name, parent_record),
|
|
102
106
|
options.merge(partition_key: partition_key, key: key))
|
|
103
107
|
end
|
|
108
|
+
parent_records.size
|
|
104
109
|
end
|
|
105
110
|
end
|
|
106
111
|
|
|
112
|
+
# Deliberately does not raise: a legitimately deleted parent is indistinguishable from
|
|
113
|
+
# one that is not visible yet, and raising on the former would retry forever.
|
|
114
|
+
def handle_nothing_published(resource, event_name, topic)
|
|
115
|
+
message = "Published nothing for #{resource.class}, id: #{resource.id}, event: #{event_name}, " \
|
|
116
|
+
"topic: #{topic} - no responder matched and no parent could be resolved. " \
|
|
117
|
+
"Make sure it's processed later (e.g. by directly doing it from console)."
|
|
118
|
+
logger.error(message)
|
|
119
|
+
instrumenter.increment("dionysus.publish.nothing_published",
|
|
120
|
+
tags: ["resource:#{resource.class}", "topic:#{topic}"])
|
|
121
|
+
error_handler.capture_message(message)
|
|
122
|
+
end
|
|
123
|
+
|
|
107
124
|
def publish_observer(observer_record, responder)
|
|
108
125
|
publishable = Dionysus::Producer::Outbox::Publishable.new(observer_record)
|
|
109
126
|
partition_key = Dionysus::Producer::PartitionKey.new(publishable).to_key(responder: responder)
|
|
@@ -8,9 +8,9 @@ class Dionysus::Producer::Registry
|
|
|
8
8
|
@container = {}
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def namespace(namespace, &
|
|
11
|
+
def namespace(namespace, &)
|
|
12
12
|
registration = Registration.new(namespace)
|
|
13
|
-
registration.instance_eval(&
|
|
13
|
+
registration.instance_eval(&)
|
|
14
14
|
container[namespace] = registration
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -32,9 +32,9 @@ class Dionysus::Producer::Registry
|
|
|
32
32
|
@serializer_klass = serializer_klass
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
def topic(name, options = {}, &
|
|
35
|
+
def topic(name, options = {}, &)
|
|
36
36
|
new_topic = Topic.new(namespace, name, serializer_klass, options)
|
|
37
|
-
new_topic.instance_eval(&
|
|
37
|
+
new_topic.instance_eval(&)
|
|
38
38
|
producer = Dionysus::Producer::KarafkaResponderGenerator.new.generate(
|
|
39
39
|
Dionysus::Producer.configuration, new_topic
|
|
40
40
|
)
|
|
@@ -119,7 +119,7 @@ class Dionysus::Producer::Registry
|
|
|
119
119
|
association_name = observer_config.fetch(:association_name)
|
|
120
120
|
_attributes = observer_config.fetch(:attributes)
|
|
121
121
|
|
|
122
|
-
if association_name.is_a?(Symbol) && !model.
|
|
122
|
+
if association_name.is_a?(Symbol) && !model.method_defined?(association_name.to_sym)
|
|
123
123
|
raise ArgumentError.new("association name :#{association_name} does not exist on model #{model}")
|
|
124
124
|
end
|
|
125
125
|
end
|
|
@@ -156,7 +156,7 @@ class Dionysus::Producer::Registry
|
|
|
156
156
|
config_model_name = observer_config.fetch(:model).to_s
|
|
157
157
|
config_attributes = observer_config.fetch(:attributes).to_a.map(&:to_sym)
|
|
158
158
|
|
|
159
|
-
config_model_name == resource_model_name && (
|
|
159
|
+
config_model_name == resource_model_name && config_attributes.intersect?(changeset_attributes)
|
|
160
160
|
end
|
|
161
161
|
end
|
|
162
162
|
end
|
data/lib/dionysus/producer.rb
CHANGED
|
@@ -13,10 +13,10 @@ class Dionysus::Producer
|
|
|
13
13
|
configuration.registry
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def self.declare(&
|
|
16
|
+
def self.declare(&)
|
|
17
17
|
registry = Dionysus::Producer::Registry.new
|
|
18
18
|
|
|
19
|
-
registry.instance_eval(&
|
|
19
|
+
registry.instance_eval(&)
|
|
20
20
|
configure do |configuration|
|
|
21
21
|
configuration.registry = registry
|
|
22
22
|
end
|
data/lib/dionysus/version.rb
CHANGED
data/lib/dionysus.rb
CHANGED
|
@@ -20,7 +20,7 @@ module Dionysus
|
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def self.initialize_application!(environment:, seed_brokers:, client_id:, logger:, draw_routing: true, consumer_group_prefix: CONSUMER_GROUP_PREFIX)
|
|
23
|
+
def self.initialize_application!(environment:, seed_brokers:, client_id:, logger:, draw_routing: true, consumer_group_prefix: CONSUMER_GROUP_PREFIX, consumer_group_name: nil)
|
|
24
24
|
ENV["KARAFKA_ENV"] = environment
|
|
25
25
|
|
|
26
26
|
karafka_app = Class.new(Karafka::App) do
|
|
@@ -37,7 +37,10 @@ module Dionysus
|
|
|
37
37
|
|
|
38
38
|
Object.const_set(:KarafkaApp, karafka_app)
|
|
39
39
|
self.karafka_application = karafka_app
|
|
40
|
-
|
|
40
|
+
return unless consumer_registry.present? && draw_routing
|
|
41
|
+
|
|
42
|
+
consumer_group_name ||= "#{consumer_group_prefix}_#{karafka_application.config.client_id}"
|
|
43
|
+
evaluate_routing(consumer_group_name: consumer_group_name)
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
def self.karafka_application=(karafka_app)
|
|
@@ -110,12 +113,11 @@ module Dionysus
|
|
|
110
113
|
@monitor ||= Dionysus::Monitor.new
|
|
111
114
|
end
|
|
112
115
|
|
|
113
|
-
def self.evaluate_routing(
|
|
114
|
-
consumer_group_name = "#{consumer_group_prefix}_#{karafka_application.config.client_id}"
|
|
116
|
+
def self.evaluate_routing(consumer_group_name:)
|
|
115
117
|
karafka_application.instance_exec(consumer_registry) do |registry|
|
|
116
118
|
consumer_groups.draw do
|
|
117
119
|
consumer_group consumer_group_name do
|
|
118
|
-
registry.registrations.
|
|
120
|
+
registry.registrations.each_value do |registration|
|
|
119
121
|
registration.topics.each do |topic|
|
|
120
122
|
topic topic.to_s do
|
|
121
123
|
consumer topic.consumer
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dionysus-rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Karol Galanciak
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -67,7 +66,7 @@ dependencies:
|
|
|
67
66
|
- !ruby/object:Gem::Version
|
|
68
67
|
version: '0'
|
|
69
68
|
- !ruby/object:Gem::Dependency
|
|
70
|
-
name:
|
|
69
|
+
name: datadog
|
|
71
70
|
requirement: !ruby/object:Gem::Requirement
|
|
72
71
|
requirements:
|
|
73
72
|
- - ">="
|
|
@@ -366,14 +365,14 @@ dependencies:
|
|
|
366
365
|
requirements:
|
|
367
366
|
- - "~>"
|
|
368
367
|
- !ruby/object:Gem::Version
|
|
369
|
-
version: '2.
|
|
368
|
+
version: '2.4'
|
|
370
369
|
type: :runtime
|
|
371
370
|
prerelease: false
|
|
372
371
|
version_requirements: !ruby/object:Gem::Requirement
|
|
373
372
|
requirements:
|
|
374
373
|
- - "~>"
|
|
375
374
|
- !ruby/object:Gem::Version
|
|
376
|
-
version: '2.
|
|
375
|
+
version: '2.4'
|
|
377
376
|
- !ruby/object:Gem::Dependency
|
|
378
377
|
name: sidekiq
|
|
379
378
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -461,6 +460,7 @@ files:
|
|
|
461
460
|
- ".rspec"
|
|
462
461
|
- ".rubocop.yml"
|
|
463
462
|
- ".rubocop_todo.yml"
|
|
463
|
+
- ".ruby-version"
|
|
464
464
|
- CHANGELOG.md
|
|
465
465
|
- Gemfile
|
|
466
466
|
- Gemfile.lock
|
|
@@ -563,7 +563,6 @@ metadata:
|
|
|
563
563
|
source_code_uri: https://github.com/BookingSync/dionysus-rb
|
|
564
564
|
changelog_uri: https://github.com/BookingSync/dionysus-rb/blob/master/CHANGELOG.md
|
|
565
565
|
rubygems_mfa_required: 'true'
|
|
566
|
-
post_install_message:
|
|
567
566
|
rdoc_options: []
|
|
568
567
|
require_paths:
|
|
569
568
|
- lib
|
|
@@ -571,15 +570,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
571
570
|
requirements:
|
|
572
571
|
- - ">="
|
|
573
572
|
- !ruby/object:Gem::Version
|
|
574
|
-
version: '
|
|
573
|
+
version: '3.3'
|
|
575
574
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
576
575
|
requirements:
|
|
577
576
|
- - ">="
|
|
578
577
|
- !ruby/object:Gem::Version
|
|
579
578
|
version: '0'
|
|
580
579
|
requirements: []
|
|
581
|
-
rubygems_version:
|
|
582
|
-
signing_key:
|
|
580
|
+
rubygems_version: 4.0.18
|
|
583
581
|
specification_version: 4
|
|
584
582
|
summary: A framework on top of Karafka for Change Data Capture on the model level.
|
|
585
583
|
test_files: []
|