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
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -21,6 +23,7 @@ module Karafka
|
|
|
21
23
|
@on_enqueued_invoked = false
|
|
22
24
|
@on_started_invoked = false
|
|
23
25
|
@on_finished_invoked = false
|
|
26
|
+
@on_revoked_invoked = false
|
|
24
27
|
@flow_lock = Mutex.new
|
|
25
28
|
end
|
|
26
29
|
|
|
@@ -79,6 +82,18 @@ module Karafka
|
|
|
79
82
|
yield(@last_message)
|
|
80
83
|
end
|
|
81
84
|
end
|
|
85
|
+
|
|
86
|
+
# Runs once when a partition is revoked
|
|
87
|
+
def on_revoked
|
|
88
|
+
@flow_lock.synchronize do
|
|
89
|
+
return unless finished?
|
|
90
|
+
return if @on_revoked_invoked
|
|
91
|
+
|
|
92
|
+
@on_revoked_invoked = true
|
|
93
|
+
|
|
94
|
+
yield(@last_message)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
82
97
|
end
|
|
83
98
|
end
|
|
84
99
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This Karafka component is a Pro component.
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
4
6
|
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
5
7
|
# repository and their usage requires commercial license agreement.
|
|
6
8
|
#
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# DLQ enabled
|
|
20
|
+
# Long-Running Job enabled
|
|
21
|
+
# Manual offset management enabled
|
|
22
|
+
#
|
|
23
|
+
# This case is a bit of special. Please see the `AjDlqMom` for explanation on how the
|
|
24
|
+
# offset management works in this case.
|
|
25
|
+
module AjDlqLrjMom
|
|
26
|
+
include AjLrjMom
|
|
27
|
+
include AjDlqMom
|
|
28
|
+
|
|
29
|
+
# Features for this strategy
|
|
30
|
+
FEATURES = %i[
|
|
31
|
+
active_job
|
|
32
|
+
long_running_job
|
|
33
|
+
manual_offset_management
|
|
34
|
+
dead_letter_queue
|
|
35
|
+
].freeze
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# DLQ enabled
|
|
20
|
+
# Manual offset management enabled
|
|
21
|
+
#
|
|
22
|
+
# AJ has manual offset management on by default and the offset management is delegated to
|
|
23
|
+
# the AJ consumer. This means, we cannot mark as consumed always. We can only mark as
|
|
24
|
+
# consumed when we skip given job upon errors. In all the other scenarions marking as
|
|
25
|
+
# consumed needs to happen in the AJ consumer on a per job basis.
|
|
26
|
+
module AjDlqMom
|
|
27
|
+
include DlqMom
|
|
28
|
+
|
|
29
|
+
# Features for this strategy
|
|
30
|
+
FEATURES = %i[
|
|
31
|
+
active_job
|
|
32
|
+
dead_letter_queue
|
|
33
|
+
manual_offset_management
|
|
34
|
+
].freeze
|
|
35
|
+
|
|
36
|
+
# How should we post-finalize consumption.
|
|
37
|
+
def handle_after_consume
|
|
38
|
+
coordinator.on_finished do
|
|
39
|
+
return if revoked?
|
|
40
|
+
|
|
41
|
+
if coordinator.success?
|
|
42
|
+
# Do NOT commit offsets, they are comitted after each job in the AJ consumer.
|
|
43
|
+
coordinator.pause_tracker.reset
|
|
44
|
+
elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
|
|
45
|
+
pause(coordinator.seek_offset)
|
|
46
|
+
else
|
|
47
|
+
coordinator.pause_tracker.reset
|
|
48
|
+
skippable_message = find_skippable_message
|
|
49
|
+
dispatch_to_dlq(skippable_message)
|
|
50
|
+
# We can commit the offset here because we know that we skip it "forever" and
|
|
51
|
+
# since AJ consumer commits the offset after each job, we also know that the
|
|
52
|
+
# previous job was successful
|
|
53
|
+
mark_as_consumed(skippable_message)
|
|
54
|
+
pause(coordinator.seek_offset)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# Long-Running Job enabled
|
|
20
|
+
# Manual offset management enabled
|
|
21
|
+
module AjLrjMom
|
|
22
|
+
# Same behaviour as LrjMom
|
|
23
|
+
include LrjMom
|
|
24
|
+
|
|
25
|
+
# Features for this strategy
|
|
26
|
+
FEATURES = %i[
|
|
27
|
+
active_job
|
|
28
|
+
long_running_job
|
|
29
|
+
manual_offset_management
|
|
30
|
+
].freeze
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# Long-Running Job enabled
|
|
20
|
+
# Manual offset management enabled
|
|
21
|
+
# Virtual Partitions enabled
|
|
22
|
+
module AjLrjMomVp
|
|
23
|
+
include Default
|
|
24
|
+
|
|
25
|
+
# Features for this strategy
|
|
26
|
+
FEATURES = %i[
|
|
27
|
+
active_job
|
|
28
|
+
long_running_job
|
|
29
|
+
manual_offset_management
|
|
30
|
+
virtual_partitions
|
|
31
|
+
].freeze
|
|
32
|
+
|
|
33
|
+
# No actions needed for the standard flow here
|
|
34
|
+
def handle_before_enqueue
|
|
35
|
+
coordinator.on_enqueued do
|
|
36
|
+
pause(coordinator.seek_offset, Lrj::MAX_PAUSE_TIME)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Standard flow without any features
|
|
41
|
+
def handle_after_consume
|
|
42
|
+
coordinator.on_finished do |last_group_message|
|
|
43
|
+
if coordinator.success?
|
|
44
|
+
coordinator.pause_tracker.reset
|
|
45
|
+
|
|
46
|
+
mark_as_consumed(last_group_message) unless revoked? || Karafka::App.stopping?
|
|
47
|
+
seek(coordinator.seek_offset) unless revoked?
|
|
48
|
+
|
|
49
|
+
resume
|
|
50
|
+
else
|
|
51
|
+
# If processing failed, we need to pause
|
|
52
|
+
# For long running job this will overwrite the default never-ending pause and will
|
|
53
|
+
# cause the processing to keep going after the error backoff
|
|
54
|
+
pause(coordinator.seek_offset)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# LRJ cannot resume here. Only in handling the after consumption
|
|
60
|
+
def handle_revoked
|
|
61
|
+
coordinator.on_revoked do
|
|
62
|
+
coordinator.revoke
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# Manual Offset management enabled
|
|
20
|
+
module AjMom
|
|
21
|
+
# Standard ActiveJob strategy is the same one we use for Mom
|
|
22
|
+
include Mom
|
|
23
|
+
|
|
24
|
+
# Features for this strategy
|
|
25
|
+
FEATURES = %i[
|
|
26
|
+
active_job
|
|
27
|
+
manual_offset_management
|
|
28
|
+
].freeze
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# ActiveJob enabled
|
|
19
|
+
# Manual offset management enabled
|
|
20
|
+
# Virtual Partitions enabled
|
|
21
|
+
module AjMomVp
|
|
22
|
+
include Default
|
|
23
|
+
|
|
24
|
+
# Features for this strategy
|
|
25
|
+
FEATURES = %i[
|
|
26
|
+
active_job
|
|
27
|
+
manual_offset_management
|
|
28
|
+
virtual_partitions
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
# Standard flow without any features
|
|
32
|
+
def handle_after_consume
|
|
33
|
+
coordinator.on_finished do |last_group_message|
|
|
34
|
+
if coordinator.success?
|
|
35
|
+
coordinator.pause_tracker.reset
|
|
36
|
+
|
|
37
|
+
# When this is an ActiveJob running via Pro with virtual partitions, we cannot mark
|
|
38
|
+
# intermediate jobs as processed not to mess up with the ordering.
|
|
39
|
+
# Only when all the jobs are processed and we did not loose the partition
|
|
40
|
+
# assignment and we are not stopping (Pro ActiveJob has an early break) we can
|
|
41
|
+
# commit offsets on this as only then we can be sure, that all the jobs were
|
|
42
|
+
# processed.
|
|
43
|
+
# For a non virtual partitions case, the flow is regular and state is marked after
|
|
44
|
+
# each successfully processed job
|
|
45
|
+
return if revoked?
|
|
46
|
+
return if Karafka::App.stopping?
|
|
47
|
+
|
|
48
|
+
mark_as_consumed(last_group_message)
|
|
49
|
+
else
|
|
50
|
+
pause(coordinator.seek_offset)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
# Pro processing strategies namespace
|
|
18
|
+
module Strategies
|
|
19
|
+
# Base strategy for Pro
|
|
20
|
+
module Base
|
|
21
|
+
include ::Karafka::Processing::Strategies::Base
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# No features enabled.
|
|
19
|
+
# No manual offset management
|
|
20
|
+
# No long running jobs
|
|
21
|
+
# No virtual partitions
|
|
22
|
+
# Nothing. Just standard, automatic flow
|
|
23
|
+
module Default
|
|
24
|
+
include Base
|
|
25
|
+
|
|
26
|
+
# Apply strategy for a non-feature based flow
|
|
27
|
+
FEATURES = %i[].freeze
|
|
28
|
+
|
|
29
|
+
# No actions needed for the standard flow here
|
|
30
|
+
def handle_before_enqueue
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Increment number of attempts per one "full" job. For all VP on a single topic partition
|
|
35
|
+
# this also should run once.
|
|
36
|
+
def handle_before_consume
|
|
37
|
+
coordinator.on_started do
|
|
38
|
+
coordinator.pause_tracker.increment
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Standard flow without any features
|
|
43
|
+
def handle_after_consume
|
|
44
|
+
coordinator.on_finished do |last_group_message|
|
|
45
|
+
return if revoked?
|
|
46
|
+
|
|
47
|
+
if coordinator.success?
|
|
48
|
+
coordinator.pause_tracker.reset
|
|
49
|
+
|
|
50
|
+
mark_as_consumed(last_group_message)
|
|
51
|
+
else
|
|
52
|
+
pause(coordinator.seek_offset)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Standard
|
|
58
|
+
def handle_revoked
|
|
59
|
+
coordinator.on_revoked do
|
|
60
|
+
resume
|
|
61
|
+
|
|
62
|
+
coordinator.revoke
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# Only dead letter queue enabled
|
|
19
|
+
module Dlq
|
|
20
|
+
include Default
|
|
21
|
+
|
|
22
|
+
# Features for this strategy
|
|
23
|
+
FEATURES = %i[
|
|
24
|
+
dead_letter_queue
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
# When we encounter non-recoverable message, we skip it and go on with our lives
|
|
28
|
+
def handle_after_consume
|
|
29
|
+
coordinator.on_finished do
|
|
30
|
+
return if revoked?
|
|
31
|
+
|
|
32
|
+
if coordinator.success?
|
|
33
|
+
coordinator.pause_tracker.reset
|
|
34
|
+
|
|
35
|
+
mark_as_consumed(messages.last)
|
|
36
|
+
elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
|
|
37
|
+
pause(coordinator.seek_offset)
|
|
38
|
+
# If we've reached number of retries that we could, we need to skip the first message
|
|
39
|
+
# that was not marked as consumed, pause and continue, while also moving this message
|
|
40
|
+
# to the dead topic
|
|
41
|
+
else
|
|
42
|
+
# We reset the pause to indicate we will now consider it as "ok".
|
|
43
|
+
coordinator.pause_tracker.reset
|
|
44
|
+
skippable_message = find_skippable_message
|
|
45
|
+
dispatch_to_dlq(skippable_message)
|
|
46
|
+
mark_as_consumed(skippable_message)
|
|
47
|
+
pause(coordinator.seek_offset)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Finds the message may want to skip (all, starting from first)
|
|
53
|
+
# @private
|
|
54
|
+
# @return [Karafka::Messages::Message] message we may want to skip
|
|
55
|
+
def find_skippable_message
|
|
56
|
+
skippable_message = messages.find { |msg| msg.offset == coordinator.seek_offset }
|
|
57
|
+
skippable_message || raise(Errors::SkipMessageNotFoundError, topic.name)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Moves the broken message into a separate queue defined via the settings
|
|
61
|
+
#
|
|
62
|
+
# @private
|
|
63
|
+
# @param skippable_message [Array<Karafka::Messages::Message>] message we want to
|
|
64
|
+
# dispatch to DLQ
|
|
65
|
+
def dispatch_to_dlq(skippable_message)
|
|
66
|
+
producer.produce_async(
|
|
67
|
+
topic: topic.dead_letter_queue.topic,
|
|
68
|
+
payload: skippable_message.raw_payload,
|
|
69
|
+
key: skippable_message.partition.to_s,
|
|
70
|
+
headers: skippable_message.headers.merge(
|
|
71
|
+
'original-topic' => topic.name,
|
|
72
|
+
'original-partition' => skippable_message.partition.to_s,
|
|
73
|
+
'original-offset' => skippable_message.offset.to_s
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
# Notify about dispatch on the events bus
|
|
78
|
+
Karafka.monitor.instrument(
|
|
79
|
+
'dead_letter_queue.dispatched',
|
|
80
|
+
caller: self,
|
|
81
|
+
message: skippable_message
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# This Karafka component is a Pro component under a commercial license.
|
|
4
|
+
# This Karafka component is NOT licensed under LGPL.
|
|
5
|
+
#
|
|
6
|
+
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
+
# repository and their usage requires commercial license agreement.
|
|
8
|
+
#
|
|
9
|
+
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
+
#
|
|
11
|
+
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
+
# your code to Maciej Mensfeld.
|
|
13
|
+
|
|
14
|
+
module Karafka
|
|
15
|
+
module Pro
|
|
16
|
+
module Processing
|
|
17
|
+
module Strategies
|
|
18
|
+
# DLQ enabled
|
|
19
|
+
# Long-Running Job enabled
|
|
20
|
+
module DlqLrj
|
|
21
|
+
# Order here matters, lrj needs to be second
|
|
22
|
+
include Dlq
|
|
23
|
+
include Lrj
|
|
24
|
+
|
|
25
|
+
# Features for this strategy
|
|
26
|
+
FEATURES = %i[
|
|
27
|
+
dead_letter_queue
|
|
28
|
+
long_running_job
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
# LRJ standard flow after consumption with DLQ dispatch
|
|
32
|
+
def handle_after_consume
|
|
33
|
+
coordinator.on_finished do |last_group_message|
|
|
34
|
+
if coordinator.success?
|
|
35
|
+
coordinator.pause_tracker.reset
|
|
36
|
+
|
|
37
|
+
mark_as_consumed(last_group_message) unless revoked?
|
|
38
|
+
seek(coordinator.seek_offset) unless revoked?
|
|
39
|
+
|
|
40
|
+
resume
|
|
41
|
+
elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
|
|
42
|
+
pause(coordinator.seek_offset)
|
|
43
|
+
else
|
|
44
|
+
coordinator.pause_tracker.reset
|
|
45
|
+
|
|
46
|
+
skippable_message = find_skippable_message
|
|
47
|
+
|
|
48
|
+
unless revoked?
|
|
49
|
+
dispatch_to_dlq(skippable_message)
|
|
50
|
+
mark_as_consumed(skippable_message)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# This revoke might have changed state due to marking, hence checked again
|
|
54
|
+
seek(coordinator.seek_offset) unless revoked?
|
|
55
|
+
|
|
56
|
+
resume
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|