karafka 2.0.15 → 2.0.16
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
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ci.yml +1 -1
- data/.rspec +2 -0
- data/CHANGELOG.md +78 -0
- data/Gemfile.lock +14 -14
- data/LICENSE +1 -1
- data/README.md +2 -1
- data/bin/integrations +3 -2
- data/bin/rspecs +4 -0
- data/config/errors.yml +10 -4
- data/lib/active_job/karafka.rb +0 -6
- data/lib/karafka/active_job/consumer.rb +1 -0
- data/lib/karafka/admin.rb +2 -2
- data/lib/karafka/base_consumer.rb +31 -21
- data/lib/karafka/connection/listener.rb +6 -4
- data/lib/karafka/contracts/consumer_group.rb +0 -14
- data/lib/karafka/contracts/{consumer_group_topic.rb → topic.rb} +2 -3
- data/lib/karafka/errors.rb +6 -4
- data/lib/karafka/instrumentation/logger_listener.rb +25 -11
- data/lib/karafka/instrumentation/notifications.rb +2 -0
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -1
- data/lib/karafka/instrumentation/vendors/datadog/listener.rb +37 -32
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +153 -0
- data/lib/karafka/pro/active_job/consumer.rb +3 -1
- data/lib/karafka/pro/active_job/dispatcher.rb +3 -1
- data/lib/karafka/pro/active_job/job_options_contract.rb +3 -1
- data/lib/karafka/pro/base_consumer.rb +3 -85
- data/lib/karafka/pro/loader.rb +31 -24
- data/lib/karafka/pro/performance_tracker.rb +3 -1
- data/lib/karafka/pro/processing/coordinator.rb +16 -1
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +3 -1
- data/lib/karafka/pro/processing/jobs_builder.rb +3 -1
- data/lib/karafka/pro/processing/partitioner.rb +3 -1
- data/lib/karafka/pro/processing/scheduler.rb +3 -1
- data/lib/karafka/pro/processing/strategies/aj_dlq_lrj_mom.rb +40 -0
- data/lib/karafka/pro/processing/strategies/aj_dlq_mom.rb +62 -0
- data/lib/karafka/pro/processing/strategies/aj_lrj_mom.rb +35 -0
- data/lib/karafka/pro/processing/strategies/aj_lrj_mom_vp.rb +69 -0
- data/lib/karafka/pro/processing/strategies/aj_mom.rb +33 -0
- data/lib/karafka/pro/processing/strategies/aj_mom_vp.rb +58 -0
- data/lib/karafka/pro/processing/strategies/base.rb +26 -0
- data/lib/karafka/pro/processing/strategies/default.rb +69 -0
- data/lib/karafka/pro/processing/strategies/dlq.rb +88 -0
- data/lib/karafka/pro/processing/strategies/dlq_lrj.rb +64 -0
- data/lib/karafka/pro/processing/strategies/dlq_lrj_mom.rb +60 -0
- data/lib/karafka/pro/processing/strategies/dlq_mom.rb +58 -0
- data/lib/karafka/pro/processing/strategies/lrj.rb +76 -0
- data/lib/karafka/pro/processing/strategies/lrj_mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/lrj_vp.rb +33 -0
- data/lib/karafka/pro/processing/strategies/mom.rb +43 -0
- data/lib/karafka/pro/processing/strategies/vp.rb +32 -0
- data/lib/karafka/pro/processing/strategy_selector.rb +58 -0
- data/lib/karafka/pro/{contracts → routing/features}/base.rb +8 -5
- data/lib/karafka/pro/routing/features/dead_letter_queue/contract.rb +49 -0
- data/lib/karafka/pro/routing/{builder_extensions.rb → features/dead_letter_queue.rb} +9 -12
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +28 -0
- data/lib/karafka/pro/routing/features/long_running_job/contract.rb +37 -0
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +42 -0
- data/lib/karafka/pro/routing/features/long_running_job.rb +28 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/contract.rb +69 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +56 -0
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +27 -0
- data/lib/karafka/processing/coordinator.rb +1 -1
- data/lib/karafka/processing/executor.rb +6 -0
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +44 -0
- data/lib/karafka/processing/strategies/aj_mom.rb +21 -0
- data/lib/karafka/processing/strategies/base.rb +37 -0
- data/lib/karafka/processing/strategies/default.rb +52 -0
- data/lib/karafka/processing/strategies/dlq.rb +77 -0
- data/lib/karafka/processing/strategies/dlq_mom.rb +42 -0
- data/lib/karafka/processing/strategies/mom.rb +29 -0
- data/lib/karafka/processing/strategy_selector.rb +30 -0
- data/lib/karafka/railtie.rb +9 -8
- data/lib/karafka/routing/builder.rb +6 -0
- data/lib/karafka/routing/features/active_job/builder.rb +33 -0
- data/lib/karafka/routing/features/active_job/config.rb +15 -0
- data/lib/karafka/routing/features/active_job/contract.rb +41 -0
- data/lib/karafka/routing/features/active_job/topic.rb +33 -0
- data/lib/karafka/routing/features/active_job.rb +13 -0
- data/lib/karafka/routing/features/base/expander.rb +53 -0
- data/lib/karafka/routing/features/base.rb +34 -0
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +19 -0
- data/lib/karafka/routing/features/dead_letter_queue/contract.rb +40 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +40 -0
- data/lib/karafka/routing/features/dead_letter_queue.rb +16 -0
- data/lib/karafka/routing/features/manual_offset_management/config.rb +15 -0
- data/lib/karafka/routing/features/manual_offset_management/contract.rb +24 -0
- data/lib/karafka/routing/features/manual_offset_management/topic.rb +35 -0
- data/lib/karafka/routing/features/manual_offset_management.rb +18 -0
- data/lib/karafka/routing/topic.rb +2 -10
- data/lib/karafka/server.rb +4 -2
- data/lib/karafka/setup/attributes_map.rb +5 -0
- data/lib/karafka/setup/config.rb +4 -4
- data/lib/karafka/time_trackers/pause.rb +21 -12
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +7 -11
- data.tar.gz.sig +0 -0
- metadata +57 -9
- metadata.gz.sig +0 -0
- data/lib/karafka/active_job/routing/extensions.rb +0 -33
- data/lib/karafka/pro/contracts/consumer_group.rb +0 -34
- data/lib/karafka/pro/contracts/consumer_group_topic.rb +0 -69
- data/lib/karafka/pro/routing/topic_extensions.rb +0 -74
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8cc0ac8b318d7c40e8974e2e26753c68cc5f611bbcd0e4fbea94e3eb275002dd
|
|
4
|
+
data.tar.gz: db638edaecc662ac8a0f7d627f4bcae6e1e1e83500a49c4dfa4a4f32ee8f78c9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6875e7e152b4150f397f3830c828412e0477409483c81e714525161e5263cff686c0cb9b46a6c11cb5b914dc51087e4bac95d5dcdc0e25c7233825b363ed7e6c
|
|
7
|
+
data.tar.gz: 1f35d410350dc3fbe97462e979f3df832484df1f1f5119e16fe2c28210d01a05e1d3e086c73e1a3b70ba3c6cae9a25dd50e0907ca454b68c9166efcabd22f972
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/.github/workflows/ci.yml
CHANGED
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,83 @@
|
|
|
1
1
|
# Karafka framework changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.16 (2022-11-09)
|
|
4
|
+
- **[Breaking]** Disable the root `manual_offset_management` setting and require it to be configured per topic. This is part of "topic features" configuration extraction for better code organization.
|
|
5
|
+
- **[Feature]** Introduce **Dead Letter Queue** feature and Pro **Enhanced Dead Letter Queue** feature
|
|
6
|
+
- [Improvement] Align attributes available in the instrumentation bus for listener related events.
|
|
7
|
+
- [Improvement] Include consumer group id in consumption related events (#1093)
|
|
8
|
+
- [Improvement] Delegate pro components loading to Zeitwerk
|
|
9
|
+
- [Improvement] Include `Datadog::LoggerListener` for tracking logger data with DataDog (@bruno-b-martins)
|
|
10
|
+
- [Improvement] Include `seek_offset` in the `consumer.consume.error` event payload (#1113)
|
|
11
|
+
- [Refactor] Remove unused logger listener event handler.
|
|
12
|
+
- [Refactor] Internal refactoring of routing validations flow.
|
|
13
|
+
- [Refactor] Reorganize how routing related features are represented internally to simplify features management.
|
|
14
|
+
- [Refactor] Extract supported features combinations processing flow into separate strategies.
|
|
15
|
+
- [Refactor] Auto-create topics in the integration specs based on the defined routing
|
|
16
|
+
- [Refactor] Auto-inject Pro components via composition instead of requiring to use `Karafka::Pro::BaseConsumer` (#1116)
|
|
17
|
+
- [Fix] Fix a case where routing tags would not be injected when given routing definition would not be used with a block
|
|
18
|
+
- [Fix] Fix a case where using `#active_job_topic` without extra block options would cause `manual_offset_management` to stay false.
|
|
19
|
+
- [Fix] Fix a case when upon Pro ActiveJob usage with Virtual Partitions, correct offset would not be stored
|
|
20
|
+
- [Fix] Fix a case where upon Virtual Partitions usage, same underlying real partition would be resumed several times.
|
|
21
|
+
- [Fix] Fix LRJ enqueuing pause increases the coordinator counter (#115)
|
|
22
|
+
- [Fix] Release `ActiveRecord` connection to the pool after the work in non-dev envs (#1130)
|
|
23
|
+
- [Fix] Fix a case where post-initialization shutdown would not initiate shutdown procedures.
|
|
24
|
+
- [Fix] Prevent Karafka from committing offsets twice upon shutdown.
|
|
25
|
+
- [Fix] Fix for a case where fast consecutive stop signaling could hang the stopping listeners.
|
|
26
|
+
- [Specs] Split specs into regular and pro to simplify how resources are loaded
|
|
27
|
+
- [Specs] Add specs to ensure, that all the Pro components have a proper per-file license (#1099)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Upgrade notes
|
|
31
|
+
|
|
32
|
+
1. Remove the `manual_offset_management` setting from the main config if you use it:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
class KarafkaApp < Karafka::App
|
|
36
|
+
setup do |config|
|
|
37
|
+
# ...
|
|
38
|
+
|
|
39
|
+
# This line needs to be removed:
|
|
40
|
+
config.manual_offset_management = true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. Set the `manual_offset_management` feature flag per each topic where you want to use it in the routing. Don't set it for topics where you want the default offset management strategy to be used.
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
class KarafkaApp < Karafka::App
|
|
49
|
+
routes.draw do
|
|
50
|
+
consumer_group :group_name do
|
|
51
|
+
topic :example do
|
|
52
|
+
consumer ExampleConsumer
|
|
53
|
+
manual_offset_management true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
topic :example2 do
|
|
57
|
+
consumer ExampleConsumer2
|
|
58
|
+
manual_offset_management true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
3. If you were using code to restart dead connections similar to this:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
class ActiveRecordConnectionsCleaner
|
|
69
|
+
def on_error_occurred(event)
|
|
70
|
+
return unless event[:error].is_a?(ActiveRecord::StatementInvalid)
|
|
71
|
+
|
|
72
|
+
::ActiveRecord::Base.clear_active_connections!
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
Karafka.monitor.subscribe(ActiveRecordConnectionsCleaner.new)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It **should** be removed. This code is **no longer needed**.
|
|
80
|
+
|
|
3
81
|
## 2.0.15 (2022-10-20)
|
|
4
82
|
- Sanitize admin config prior to any admin action.
|
|
5
83
|
- Make messages partitioner outcome for virtual partitions consistently distributed in regards to concurrency.
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
karafka (2.0.
|
|
4
|
+
karafka (2.0.16)
|
|
5
5
|
karafka-core (>= 2.0.2, < 3.0.0)
|
|
6
6
|
rdkafka (>= 0.12)
|
|
7
7
|
thor (>= 0.20)
|
|
@@ -39,19 +39,19 @@ GEM
|
|
|
39
39
|
ffi (~> 1.15)
|
|
40
40
|
mini_portile2 (~> 2.6)
|
|
41
41
|
rake (> 12)
|
|
42
|
-
rspec (3.
|
|
43
|
-
rspec-core (~> 3.
|
|
44
|
-
rspec-expectations (~> 3.
|
|
45
|
-
rspec-mocks (~> 3.
|
|
46
|
-
rspec-core (3.
|
|
47
|
-
rspec-support (~> 3.
|
|
48
|
-
rspec-expectations (3.
|
|
42
|
+
rspec (3.12.0)
|
|
43
|
+
rspec-core (~> 3.12.0)
|
|
44
|
+
rspec-expectations (~> 3.12.0)
|
|
45
|
+
rspec-mocks (~> 3.12.0)
|
|
46
|
+
rspec-core (3.12.0)
|
|
47
|
+
rspec-support (~> 3.12.0)
|
|
48
|
+
rspec-expectations (3.12.0)
|
|
49
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
50
|
-
rspec-support (~> 3.
|
|
51
|
-
rspec-mocks (3.
|
|
50
|
+
rspec-support (~> 3.12.0)
|
|
51
|
+
rspec-mocks (3.12.0)
|
|
52
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
53
|
-
rspec-support (~> 3.
|
|
54
|
-
rspec-support (3.
|
|
53
|
+
rspec-support (~> 3.12.0)
|
|
54
|
+
rspec-support (3.12.0)
|
|
55
55
|
simplecov (0.21.2)
|
|
56
56
|
docile (~> 1.1)
|
|
57
57
|
simplecov-html (~> 0.11)
|
|
@@ -65,7 +65,7 @@ GEM
|
|
|
65
65
|
karafka-core (>= 2.0.2, < 3.0.0)
|
|
66
66
|
rdkafka (>= 0.10)
|
|
67
67
|
zeitwerk (~> 2.3)
|
|
68
|
-
zeitwerk (2.6.
|
|
68
|
+
zeitwerk (2.6.6)
|
|
69
69
|
|
|
70
70
|
PLATFORMS
|
|
71
71
|
x86_64-linux
|
|
@@ -79,4 +79,4 @@ DEPENDENCIES
|
|
|
79
79
|
simplecov
|
|
80
80
|
|
|
81
81
|
BUNDLED WITH
|
|
82
|
-
2.3.
|
|
82
|
+
2.3.24
|
data/LICENSE
CHANGED
|
@@ -12,6 +12,6 @@ and their usage requires commercial license agreement.
|
|
|
12
12
|
By sending a pull request to the pro components, you are agreeing to transfer the copyright of your
|
|
13
13
|
code to Maciej Mensfeld.
|
|
14
14
|
|
|
15
|
-
You can find the commercial license in LICENSE-
|
|
15
|
+
You can find the commercial license in LICENSE-COMM.
|
|
16
16
|
|
|
17
17
|
Please see https://karafka.io for purchasing options.
|
data/README.md
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
Karafka is a Ruby and Rails multi-threaded efficient Kafka processing framework that:
|
|
10
10
|
|
|
11
11
|
- Supports parallel processing in [multiple threads](https://karafka.io/docs/Concurrency-and-multithreading) (also for a [single topic partition](https://karafka.io/docs/Pro-Virtual-Partitions) work)
|
|
12
|
-
- Has [ActiveJob backend](https://karafka.io/docs/Active-Job) support (including [ordered jobs](https://karafka.io/docs/Pro-Enhanced-Active-Job#ordered-jobs))
|
|
13
12
|
- [Automatically integrates](https://karafka.io/docs/Integrating-with-Ruby-on-Rails-and-other-frameworks#integrating-with-ruby-on-rails) with Ruby on Rails
|
|
13
|
+
- Has [ActiveJob backend](https://karafka.io/docs/Active-Job) support (including [ordered jobs](https://karafka.io/docs/Pro-Enhanced-Active-Job#ordered-jobs))
|
|
14
|
+
- Has a seamless [Dead Letter Queue](karafka.io/docs/Dead-Letter-Queue/) functionality built-in
|
|
14
15
|
- Supports in-development [code reloading](https://karafka.io/docs/Auto-reload-of-code-changes-in-development)
|
|
15
16
|
- Is powered by [librdkafka](https://github.com/edenhill/librdkafka) (the Apache Kafka C/C++ client library)
|
|
16
17
|
- Has an out-of the box [StatsD/DataDog monitoring](https://karafka.io/docs/Monitoring-and-logging) with a dashboard template.
|
data/bin/integrations
CHANGED
|
@@ -21,9 +21,10 @@ require 'etc'
|
|
|
21
21
|
ROOT_PATH = Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), '../')))
|
|
22
22
|
|
|
23
23
|
# How many child processes with integration specs do we want to run in parallel
|
|
24
|
-
# When the value is high, there's a problem with thread allocation on Github CI,
|
|
24
|
+
# When the value is high, there's a problem with thread allocation on Github CI, that is why
|
|
25
25
|
# we limit it. Locally we can run a lot of those, as many of them have sleeps and do not use a lot
|
|
26
|
-
# of CPU
|
|
26
|
+
# of CPU. Locally we also cannot go beyond certain limit due to how often and how many topics we
|
|
27
|
+
# create in Kafka. With an overloaded system, we start getting timeouts.
|
|
27
28
|
CONCURRENCY = ENV.key?('CI') ? 4 : Etc.nprocessors * 2
|
|
28
29
|
|
|
29
30
|
# How may bytes do we want to keep from the stdout in the buffer for when we need to print it
|
data/bin/rspecs
ADDED
data/config/errors.yml
CHANGED
|
@@ -27,15 +27,20 @@ en:
|
|
|
27
27
|
missing: needs to be present
|
|
28
28
|
consumer_groups_inclusion: Unknown consumer group
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
topic:
|
|
31
31
|
missing: needs to be present
|
|
32
32
|
name_format: 'needs to be a string with a Kafka accepted format'
|
|
33
33
|
deserializer_format: needs to be present
|
|
34
|
-
manual_offset_management_format: needs to be either true or false
|
|
35
34
|
consumer_format: needs to be present
|
|
36
35
|
id_format: 'needs to be a string with a Kafka accepted format'
|
|
37
36
|
initial_offset_format: needs to be either earliest or latest
|
|
38
37
|
subscription_group_format: must be nil or a non-empty string
|
|
38
|
+
manual_offset_management.active_format: needs to be either true or false
|
|
39
|
+
consumer_active_job_missing: ActiveJob needs to be available
|
|
40
|
+
manual_offset_management_must_be_enabled: cannot be disabled for ActiveJob topics
|
|
41
|
+
dead_letter_queue.max_retries_format: needs to be equal or bigger than 0
|
|
42
|
+
dead_letter_queue.topic_format: 'needs to be a string with a Kafka accepted format'
|
|
43
|
+
dead_letter_queue.active_format: needs to be either true or false
|
|
39
44
|
|
|
40
45
|
consumer_group:
|
|
41
46
|
missing: needs to be present
|
|
@@ -53,8 +58,9 @@ en:
|
|
|
53
58
|
missing: needs to be present
|
|
54
59
|
id_format: needs to be a String
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
consumer_format: needs to inherit from Karafka::Pro::BaseConsumer and not Karafka::Consumer
|
|
61
|
+
pro_topic:
|
|
58
62
|
virtual_partitions.partitioner_respond_to_call: needs to be defined and needs to respond to `#call`
|
|
59
63
|
virtual_partitions.max_partitions_format: needs to be equl or more than 1
|
|
60
64
|
manual_offset_management_not_with_virtual_partitions: cannot be used together with Virtual Partitions
|
|
65
|
+
long_running_job.active_format: needs to be either true or false
|
|
66
|
+
dead_letter_queue_not_with_virtual_partitions: cannot be used together with Virtual Partitions
|
data/lib/active_job/karafka.rb
CHANGED
|
@@ -10,12 +10,6 @@ begin
|
|
|
10
10
|
module Karafka
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
|
-
|
|
14
|
-
# We extend routing builder by adding a simple wrapper for easier jobs topics defining
|
|
15
|
-
# This needs to be extended here as it is going to be used in karafka routes, hence doing that in
|
|
16
|
-
# the railtie initializer would be too late
|
|
17
|
-
::Karafka::Routing::Builder.include ::Karafka::ActiveJob::Routing::Extensions
|
|
18
|
-
::Karafka::Routing::Proxy.include ::Karafka::ActiveJob::Routing::Extensions
|
|
19
13
|
rescue LoadError
|
|
20
14
|
# We extend ActiveJob stuff in the railtie
|
|
21
15
|
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
|
+
# Namespace for all the ActiveJob related things from within Karafka
|
|
4
5
|
module ActiveJob
|
|
5
6
|
# This is the consumer for ActiveJob that eats the messages enqueued with it one after another.
|
|
6
7
|
# It marks the offset after each message, so we make sure, none of the jobs is executed twice
|
data/lib/karafka/admin.rb
CHANGED
|
@@ -21,7 +21,7 @@ module Karafka
|
|
|
21
21
|
with_admin do |admin|
|
|
22
22
|
admin.create_topic(name, partitions, replication_factor, topic_config)
|
|
23
23
|
|
|
24
|
-
sleep(0.
|
|
24
|
+
sleep(0.2) until topics_names.include?(name)
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -32,7 +32,7 @@ module Karafka
|
|
|
32
32
|
with_admin do |admin|
|
|
33
33
|
admin.delete_topic(name)
|
|
34
34
|
|
|
35
|
-
sleep(0.
|
|
35
|
+
sleep(0.2) while topics_names.include?(name)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
@@ -21,7 +21,16 @@ module Karafka
|
|
|
21
21
|
# @note This should not be used by the end users as it is part of the lifecycle of things and
|
|
22
22
|
# not as a part of the public api. This should not perform any extensive operations as it is
|
|
23
23
|
# blocking and running in the listener thread.
|
|
24
|
-
def on_before_enqueue
|
|
24
|
+
def on_before_enqueue
|
|
25
|
+
handle_before_enqueue
|
|
26
|
+
rescue StandardError => e
|
|
27
|
+
Karafka.monitor.instrument(
|
|
28
|
+
'error.occurred',
|
|
29
|
+
error: e,
|
|
30
|
+
caller: self,
|
|
31
|
+
type: 'consumer.before_enqueue.error'
|
|
32
|
+
)
|
|
33
|
+
end
|
|
25
34
|
|
|
26
35
|
# Can be used to run preparation code in the worker
|
|
27
36
|
#
|
|
@@ -32,6 +41,17 @@ module Karafka
|
|
|
32
41
|
def on_before_consume
|
|
33
42
|
messages.metadata.processed_at = Time.now
|
|
34
43
|
messages.metadata.freeze
|
|
44
|
+
|
|
45
|
+
# We run this after the full metadata setup, so we can use all the messages information
|
|
46
|
+
# if needed
|
|
47
|
+
handle_before_consume
|
|
48
|
+
rescue StandardError => e
|
|
49
|
+
Karafka.monitor.instrument(
|
|
50
|
+
'error.occurred',
|
|
51
|
+
error: e,
|
|
52
|
+
caller: self,
|
|
53
|
+
type: 'consumer.before_consume.error'
|
|
54
|
+
)
|
|
35
55
|
end
|
|
36
56
|
|
|
37
57
|
# Executes the default consumer flow.
|
|
@@ -54,6 +74,7 @@ module Karafka
|
|
|
54
74
|
'error.occurred',
|
|
55
75
|
error: e,
|
|
56
76
|
caller: self,
|
|
77
|
+
seek_offset: coordinator.seek_offset,
|
|
57
78
|
type: 'consumer.consume.error'
|
|
58
79
|
)
|
|
59
80
|
ensure
|
|
@@ -65,32 +86,21 @@ module Karafka
|
|
|
65
86
|
# @note This should not be used by the end users as it is part of the lifecycle of things but
|
|
66
87
|
# not as part of the public api.
|
|
67
88
|
def on_after_consume
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# We use the non-blocking one here. If someone needs the blocking one, can implement it
|
|
77
|
-
# with manual offset management
|
|
78
|
-
mark_as_consumed(messages.last)
|
|
79
|
-
else
|
|
80
|
-
pause(coordinator.seek_offset)
|
|
81
|
-
end
|
|
89
|
+
handle_after_consume
|
|
90
|
+
rescue StandardError => e
|
|
91
|
+
Karafka.monitor.instrument(
|
|
92
|
+
'error.occurred',
|
|
93
|
+
error: e,
|
|
94
|
+
caller: self,
|
|
95
|
+
type: 'consumer.after_consume.error'
|
|
96
|
+
)
|
|
82
97
|
end
|
|
83
98
|
|
|
84
99
|
# Trigger method for running on partition revocation.
|
|
85
100
|
#
|
|
86
101
|
# @private
|
|
87
102
|
def on_revoked
|
|
88
|
-
|
|
89
|
-
# Otherwise the underlying librdkafka would not know we may want to continue processing and
|
|
90
|
-
# the pause could in theory last forever
|
|
91
|
-
resume
|
|
92
|
-
|
|
93
|
-
coordinator.revoke
|
|
103
|
+
handle_revoked
|
|
94
104
|
|
|
95
105
|
Karafka.monitor.instrument('consumer.revoked', caller: self) do
|
|
96
106
|
revoked
|
|
@@ -46,8 +46,8 @@ module Karafka
|
|
|
46
46
|
Karafka.monitor.instrument(
|
|
47
47
|
'connection.listener.before_fetch_loop',
|
|
48
48
|
caller: self,
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
client: @client,
|
|
50
|
+
subscription_group: @subscription_group
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
fetch_loop
|
|
@@ -67,7 +67,6 @@ module Karafka
|
|
|
67
67
|
@stopped = true
|
|
68
68
|
@executors.clear
|
|
69
69
|
@coordinators.reset
|
|
70
|
-
@client.commit_offsets!
|
|
71
70
|
@client.stop
|
|
72
71
|
end
|
|
73
72
|
end
|
|
@@ -87,7 +86,8 @@ module Karafka
|
|
|
87
86
|
Karafka.monitor.instrument(
|
|
88
87
|
'connection.listener.fetch_loop',
|
|
89
88
|
caller: self,
|
|
90
|
-
client: @client
|
|
89
|
+
client: @client,
|
|
90
|
+
subscription_group: @subscription_group
|
|
91
91
|
)
|
|
92
92
|
|
|
93
93
|
resume_paused_partitions
|
|
@@ -95,6 +95,8 @@ module Karafka
|
|
|
95
95
|
Karafka.monitor.instrument(
|
|
96
96
|
'connection.listener.fetch_loop.received',
|
|
97
97
|
caller: self,
|
|
98
|
+
client: @client,
|
|
99
|
+
subscription_group: @subscription_group,
|
|
98
100
|
messages_buffer: @messages_buffer
|
|
99
101
|
) do
|
|
100
102
|
# We need to fetch data before we revoke lost partitions details as during the polling
|
|
@@ -24,20 +24,6 @@ module Karafka
|
|
|
24
24
|
|
|
25
25
|
[[%i[topics], :names_not_unique]]
|
|
26
26
|
end
|
|
27
|
-
|
|
28
|
-
virtual do |data, errors|
|
|
29
|
-
next unless errors.empty?
|
|
30
|
-
|
|
31
|
-
fetched_errors = []
|
|
32
|
-
|
|
33
|
-
data.fetch(:topics).each do |topic|
|
|
34
|
-
ConsumerGroupTopic.new.call(topic).errors.each do |key, value|
|
|
35
|
-
fetched_errors << [[topic, key].flatten, value]
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
fetched_errors
|
|
40
|
-
end
|
|
41
27
|
end
|
|
42
28
|
end
|
|
43
29
|
end
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Contracts
|
|
5
5
|
# Consumer group topic validation rules.
|
|
6
|
-
class
|
|
6
|
+
class Topic < Base
|
|
7
7
|
configure do |config|
|
|
8
8
|
config.error_messages = YAML.safe_load(
|
|
9
9
|
File.read(
|
|
10
10
|
File.join(Karafka.gem_root, 'config', 'errors.yml')
|
|
11
11
|
)
|
|
12
|
-
).fetch('en').fetch('validations').fetch('
|
|
12
|
+
).fetch('en').fetch('validations').fetch('topic')
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
required(:consumer) { |val| !val.nil? }
|
|
@@ -19,7 +19,6 @@ module Karafka
|
|
|
19
19
|
required(:max_messages) { |val| val.is_a?(Integer) && val >= 1 }
|
|
20
20
|
required(:initial_offset) { |val| %w[earliest latest].include?(val) }
|
|
21
21
|
required(:max_wait_time) { |val| val.is_a?(Integer) && val >= 10 }
|
|
22
|
-
required(:manual_offset_management) { |val| [true, false].include?(val) }
|
|
23
22
|
required(:name) { |val| val.is_a?(String) && Contracts::TOPIC_REGEXP.match?(val) }
|
|
24
23
|
required(:subscription_group) { |val| val.nil? || (val.is_a?(String) && !val.empty?) }
|
|
25
24
|
|
data/lib/karafka/errors.rb
CHANGED
|
@@ -41,11 +41,13 @@ module Karafka
|
|
|
41
41
|
# Raised when the license token is not valid
|
|
42
42
|
InvalidLicenseTokenError = Class.new(BaseError)
|
|
43
43
|
|
|
44
|
-
#
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
# This should never happen. Please open an issue if it does.
|
|
45
|
+
InvalidCoordinatorStateError = Class.new(BaseError)
|
|
46
|
+
|
|
47
|
+
# This should never happen. Please open an issue if it does.
|
|
48
|
+
StrategyNotFoundError = Class.new(BaseError)
|
|
47
49
|
|
|
48
50
|
# This should never happen. Please open an issue if it does.
|
|
49
|
-
|
|
51
|
+
SkipMessageNotFoundError = Class.new(BaseError)
|
|
50
52
|
end
|
|
51
53
|
end
|
|
@@ -14,6 +14,8 @@ module Karafka
|
|
|
14
14
|
fatal
|
|
15
15
|
].freeze
|
|
16
16
|
|
|
17
|
+
private_constant :USED_LOG_LEVELS
|
|
18
|
+
|
|
17
19
|
# Logs each messages fetching attempt
|
|
18
20
|
#
|
|
19
21
|
# @param event [Dry::Events::Event] event details including payload
|
|
@@ -85,13 +87,6 @@ module Karafka
|
|
|
85
87
|
end
|
|
86
88
|
end
|
|
87
89
|
|
|
88
|
-
# Logs info that we're initializing Karafka app.
|
|
89
|
-
#
|
|
90
|
-
# @param _event [Dry::Events::Event] event details including payload
|
|
91
|
-
def on_app_initializing(_event)
|
|
92
|
-
info 'Initializing Karafka framework'
|
|
93
|
-
end
|
|
94
|
-
|
|
95
90
|
# Logs info that we're running Karafka app.
|
|
96
91
|
#
|
|
97
92
|
# @param _event [Dry::Events::Event] event details including payload
|
|
@@ -118,6 +113,19 @@ module Karafka
|
|
|
118
113
|
info 'Stopped Karafka server'
|
|
119
114
|
end
|
|
120
115
|
|
|
116
|
+
# Logs info when we have dispatched a message the the DLQ
|
|
117
|
+
#
|
|
118
|
+
# @param event [Dry::Events::Event] event details including payload
|
|
119
|
+
def on_dead_letter_queue_dispatched(event)
|
|
120
|
+
message = event[:message]
|
|
121
|
+
offset = message.offset
|
|
122
|
+
topic = event[:caller].topic.name
|
|
123
|
+
dlq_topic = event[:caller].topic.dead_letter_queue.topic
|
|
124
|
+
partition = message.partition
|
|
125
|
+
|
|
126
|
+
info "Dispatched message #{offset} from #{topic}/#{partition} to DQL topic: #{dlq_topic}"
|
|
127
|
+
end
|
|
128
|
+
|
|
121
129
|
# There are many types of errors that can occur in many places, but we provide a single
|
|
122
130
|
# handler for all of them to simplify error instrumentation.
|
|
123
131
|
# @param event [Dry::Events::Event] event details including payload
|
|
@@ -133,6 +141,15 @@ module Karafka
|
|
|
133
141
|
when 'consumer.revoked.error'
|
|
134
142
|
error "Consumer on revoked failed due to an error: #{error}"
|
|
135
143
|
error details
|
|
144
|
+
when 'consumer.before_enqueue.error'
|
|
145
|
+
error "Consumer before enqueue failed due to an error: #{error}"
|
|
146
|
+
error details
|
|
147
|
+
when 'consumer.before_consume.error'
|
|
148
|
+
error "Consumer before consume failed due to an error: #{error}"
|
|
149
|
+
error details
|
|
150
|
+
when 'consumer.after_consume.error'
|
|
151
|
+
error "Consumer after consume failed due to an error: #{error}"
|
|
152
|
+
error details
|
|
136
153
|
when 'consumer.shutdown.error'
|
|
137
154
|
error "Consumer on shutdown failed due to an error: #{error}"
|
|
138
155
|
error details
|
|
@@ -142,9 +159,6 @@ module Karafka
|
|
|
142
159
|
when 'connection.listener.fetch_loop.error'
|
|
143
160
|
error "Listener fetch loop error: #{error}"
|
|
144
161
|
error details
|
|
145
|
-
when 'licenser.expired'
|
|
146
|
-
error error
|
|
147
|
-
error details
|
|
148
162
|
when 'runner.call.error'
|
|
149
163
|
fatal "Runner crashed due to an error: #{error}"
|
|
150
164
|
fatal details
|
|
@@ -154,7 +168,7 @@ module Karafka
|
|
|
154
168
|
error "librdkafka internal error occurred: #{error}"
|
|
155
169
|
error details
|
|
156
170
|
# Those will only occur when retries in the client fail and when they did not stop after
|
|
157
|
-
#
|
|
171
|
+
# back-offs
|
|
158
172
|
when 'connection.client.poll.error'
|
|
159
173
|
error "Data polling error occurred: #{error}"
|
|
160
174
|
error details
|