karafka 2.0.0 → 2.1.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
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/ci.yml +40 -16
- data/.rspec +4 -0
- data/.ruby-version +1 -1
- data/CHANGELOG.md +459 -796
- data/Gemfile +3 -2
- data/Gemfile.lock +44 -32
- data/LICENSE +1 -1
- data/README.md +22 -17
- data/bin/integrations +86 -26
- data/bin/karafka +1 -13
- data/bin/rspecs +6 -0
- data/bin/verify_license_integrity +37 -0
- data/certs/cert_chain.pem +26 -0
- data/config/{errors.yml → locales/errors.yml} +34 -6
- data/config/locales/pro_errors.yml +34 -0
- data/docker-compose.yml +4 -30
- data/karafka.gemspec +17 -10
- data/lib/active_job/karafka.rb +3 -7
- data/lib/active_job/queue_adapters/karafka_adapter.rb +7 -1
- data/lib/karafka/active_job/consumer.rb +29 -6
- data/lib/karafka/active_job/current_attributes/loading.rb +36 -0
- data/lib/karafka/active_job/current_attributes/persistence.rb +28 -0
- data/lib/karafka/active_job/current_attributes.rb +42 -0
- data/lib/karafka/active_job/dispatcher.rb +34 -3
- data/lib/karafka/active_job/job_options_contract.rb +13 -2
- data/lib/karafka/admin.rb +246 -0
- data/lib/karafka/app.rb +30 -7
- data/lib/karafka/base_consumer.rb +124 -82
- data/lib/karafka/cli/base.rb +20 -0
- data/lib/karafka/cli/console.rb +13 -8
- data/lib/karafka/cli/info.rb +3 -2
- data/lib/karafka/cli/server.rb +55 -8
- data/lib/karafka/cli/topics.rb +146 -0
- data/lib/karafka/connection/client.rb +118 -61
- data/lib/karafka/connection/consumer_group_coordinator.rb +48 -0
- data/lib/karafka/connection/listener.rb +78 -30
- data/lib/karafka/connection/listeners_batch.rb +18 -2
- data/lib/karafka/connection/rebalance_manager.rb +3 -0
- data/lib/karafka/contracts/config.rb +1 -1
- data/lib/karafka/contracts/consumer_group.rb +22 -9
- data/lib/karafka/contracts/server_cli_options.rb +71 -11
- data/lib/karafka/contracts/topic.rb +65 -0
- data/lib/karafka/contracts.rb +1 -1
- data/lib/karafka/embedded.rb +36 -0
- data/lib/karafka/errors.rb +6 -4
- data/lib/karafka/helpers/colorize.rb +6 -0
- data/lib/karafka/instrumentation/callbacks/error.rb +3 -4
- data/lib/karafka/instrumentation/callbacks/statistics.rb +14 -4
- data/lib/karafka/instrumentation/logger_listener.rb +151 -22
- data/lib/karafka/instrumentation/notifications.rb +26 -7
- data/lib/karafka/instrumentation/proctitle_listener.rb +7 -16
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -1
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +153 -0
- data/lib/karafka/instrumentation/vendors/datadog/{listener.rb → metrics_listener.rb} +62 -35
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +166 -0
- data/lib/karafka/licenser.rb +53 -50
- data/lib/karafka/messages/builders/batch_metadata.rb +8 -8
- data/lib/karafka/messages/builders/messages.rb +6 -2
- data/lib/karafka/messages/message.rb +14 -2
- data/lib/karafka/messages/messages.rb +5 -0
- data/lib/karafka/messages/parser.rb +14 -0
- data/lib/karafka/patches/rdkafka/bindings.rb +132 -0
- data/lib/karafka/pro/active_job/consumer.rb +10 -9
- data/lib/karafka/pro/active_job/dispatcher.rb +28 -3
- data/lib/karafka/pro/active_job/job_options_contract.rb +16 -3
- data/lib/karafka/pro/encryption/cipher.rb +58 -0
- data/lib/karafka/pro/encryption/contracts/config.rb +79 -0
- data/lib/karafka/pro/encryption/errors.rb +24 -0
- data/lib/karafka/pro/encryption/messages/middleware.rb +46 -0
- data/lib/karafka/pro/encryption/messages/parser.rb +56 -0
- data/lib/karafka/pro/encryption/setup/config.rb +48 -0
- data/lib/karafka/pro/encryption.rb +47 -0
- data/lib/karafka/pro/iterator.rb +253 -0
- data/lib/karafka/pro/loader.rb +52 -26
- data/lib/karafka/pro/performance_tracker.rb +10 -6
- data/lib/karafka/pro/processing/collapser.rb +62 -0
- data/lib/karafka/pro/processing/coordinator.rb +92 -16
- data/lib/karafka/pro/processing/filters/base.rb +61 -0
- data/lib/karafka/pro/processing/filters/delayer.rb +70 -0
- data/lib/karafka/pro/processing/filters/expirer.rb +51 -0
- data/lib/karafka/pro/processing/filters/throttler.rb +84 -0
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +52 -0
- data/lib/karafka/pro/processing/filters_applier.rb +104 -0
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +7 -5
- data/lib/karafka/pro/processing/jobs/revoked_non_blocking.rb +37 -0
- data/lib/karafka/pro/processing/jobs_builder.rb +22 -4
- data/lib/karafka/pro/processing/partitioner.rb +33 -24
- data/lib/karafka/pro/processing/scheduler.rb +27 -8
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +74 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +72 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +76 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +68 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +69 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +64 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +38 -0
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +58 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +37 -0
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +79 -0
- data/lib/karafka/pro/processing/strategies/aj/mom.rb +36 -0
- data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +52 -0
- data/lib/karafka/pro/processing/strategies/base.rb +26 -0
- data/lib/karafka/pro/processing/strategies/default.rb +105 -0
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +131 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +61 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +75 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +71 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +43 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +69 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +41 -0
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +63 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom_vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +68 -0
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +104 -0
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +87 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +69 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +67 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +40 -0
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +39 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +80 -0
- data/lib/karafka/pro/processing/strategies/lrj/mom_vp.rb +38 -0
- data/lib/karafka/pro/processing/strategies/lrj/vp.rb +36 -0
- data/lib/karafka/pro/processing/strategies/mom/default.rb +46 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr.rb +53 -0
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +37 -0
- data/lib/karafka/pro/processing/strategies/mom/vp.rb +35 -0
- data/lib/karafka/pro/processing/strategies/vp/default.rb +104 -0
- data/lib/karafka/pro/{contracts/base.rb → processing/strategies.rb} +6 -5
- data/lib/karafka/pro/processing/strategy_selector.rb +84 -0
- data/lib/karafka/pro/processing/virtual_offset_manager.rb +147 -0
- data/lib/karafka/pro/routing/features/base.rb +24 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue/contract.rb +50 -0
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +27 -0
- data/lib/karafka/pro/routing/{builder_extensions.rb → features/delaying/config.rb} +8 -11
- data/lib/karafka/pro/routing/features/delaying/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/delaying/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/delaying.rb +29 -0
- data/lib/karafka/pro/routing/features/expiring/config.rb +27 -0
- data/lib/karafka/pro/routing/features/expiring/contract.rb +38 -0
- data/lib/karafka/pro/routing/features/expiring/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/expiring.rb +27 -0
- data/lib/karafka/pro/routing/features/filtering/config.rb +40 -0
- data/lib/karafka/pro/routing/features/filtering/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/filtering/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/filtering.rb +27 -0
- 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/throttling/config.rb +32 -0
- data/lib/karafka/pro/routing/features/throttling/contract.rb +41 -0
- data/lib/karafka/pro/routing/features/throttling/topic.rb +69 -0
- data/lib/karafka/pro/routing/features/throttling.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +30 -0
- data/lib/karafka/pro/routing/features/virtual_partitions/contract.rb +52 -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/process.rb +23 -8
- data/lib/karafka/processing/coordinator.rb +102 -23
- data/lib/karafka/processing/coordinators_buffer.rb +5 -1
- data/lib/karafka/processing/executor.rb +51 -21
- data/lib/karafka/processing/executors_buffer.rb +10 -26
- data/lib/karafka/processing/jobs/base.rb +6 -2
- data/lib/karafka/processing/jobs/consume.rb +8 -5
- data/lib/karafka/processing/jobs/idle.rb +24 -0
- data/lib/karafka/processing/jobs_builder.rb +2 -3
- data/lib/karafka/processing/jobs_queue.rb +14 -8
- data/lib/karafka/processing/partitioner.rb +3 -1
- data/lib/karafka/processing/result.rb +14 -1
- 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 +52 -0
- data/lib/karafka/processing/strategies/default.rb +142 -0
- data/lib/karafka/processing/strategies/dlq.rb +88 -0
- data/lib/karafka/processing/strategies/dlq_mom.rb +49 -0
- data/lib/karafka/processing/strategies/mom.rb +29 -0
- data/lib/karafka/processing/strategy_selector.rb +47 -0
- data/lib/karafka/processing/worker.rb +8 -3
- data/lib/karafka/railtie.rb +24 -12
- data/lib/karafka/routing/activity_manager.rb +84 -0
- data/lib/karafka/routing/builder.rb +20 -0
- data/lib/karafka/routing/consumer_group.rb +38 -4
- data/lib/karafka/routing/consumer_mapper.rb +0 -10
- 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 +42 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +41 -0
- data/lib/karafka/routing/features/dead_letter_queue.rb +16 -0
- data/lib/karafka/routing/features/declaratives/config.rb +18 -0
- data/lib/karafka/routing/features/declaratives/contract.rb +30 -0
- data/lib/karafka/routing/features/declaratives/topic.rb +44 -0
- data/lib/karafka/routing/features/declaratives.rb +14 -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/proxy.rb +18 -20
- data/lib/karafka/routing/router.rb +27 -2
- data/lib/karafka/routing/subscription_group.rb +43 -5
- data/lib/karafka/routing/subscription_groups_builder.rb +6 -1
- data/lib/karafka/routing/topic.rb +17 -5
- data/lib/karafka/routing/topics.rb +8 -0
- data/lib/karafka/runner.rb +1 -0
- data/lib/karafka/serialization/json/deserializer.rb +1 -0
- data/lib/karafka/server.rb +58 -28
- data/lib/karafka/setup/attributes_map.rb +344 -0
- data/lib/karafka/setup/config.rb +48 -19
- data/lib/karafka/status.rb +35 -7
- data/lib/karafka/templates/karafka.rb.erb +14 -6
- data/lib/karafka/time_trackers/base.rb +1 -6
- data/lib/karafka/time_trackers/pause.rb +49 -19
- data/lib/karafka/time_trackers/poll.rb +7 -3
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +56 -3
- data/renovate.json +6 -0
- data.tar.gz.sig +0 -0
- metadata +189 -61
- metadata.gz.sig +0 -0
- data/bin/wait_for_kafka +0 -20
- data/certs/mensfeld.pem +0 -25
- data/lib/karafka/active_job/routing/extensions.rb +0 -31
- data/lib/karafka/contracts/consumer_group_topic.rb +0 -42
- data/lib/karafka/instrumentation.rb +0 -21
- data/lib/karafka/pro/base_consumer.rb +0 -82
- data/lib/karafka/pro/contracts/consumer_group.rb +0 -34
- data/lib/karafka/pro/contracts/consumer_group_topic.rb +0 -33
- data/lib/karafka/pro/routing/topic_extensions.rb +0 -38
|
@@ -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
|
#
|
|
@@ -15,12 +17,30 @@ module Karafka
|
|
|
15
17
|
# Pro coordinator that provides extra orchestration methods useful for parallel processing
|
|
16
18
|
# within the same partition
|
|
17
19
|
class Coordinator < ::Karafka::Processing::Coordinator
|
|
20
|
+
attr_reader :filter, :virtual_offset_manager
|
|
21
|
+
|
|
18
22
|
# @param args [Object] anything the base coordinator accepts
|
|
19
23
|
def initialize(*args)
|
|
20
24
|
super
|
|
21
|
-
|
|
22
|
-
@
|
|
25
|
+
|
|
26
|
+
@executed = []
|
|
23
27
|
@flow_lock = Mutex.new
|
|
28
|
+
@collapser = Collapser.new
|
|
29
|
+
@filter = FiltersApplier.new(self)
|
|
30
|
+
|
|
31
|
+
return unless topic.virtual_partitions?
|
|
32
|
+
|
|
33
|
+
@virtual_offset_manager = VirtualOffsetManager.new(
|
|
34
|
+
topic.name,
|
|
35
|
+
partition
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# We register our own "internal" filter to support filtering of messages that were marked
|
|
39
|
+
# as consumed virtually
|
|
40
|
+
@filter.filters << Filters::VirtualLimiter.new(
|
|
41
|
+
@virtual_offset_manager,
|
|
42
|
+
@collapser
|
|
43
|
+
)
|
|
24
44
|
end
|
|
25
45
|
|
|
26
46
|
# Starts the coordination process
|
|
@@ -29,12 +49,37 @@ module Karafka
|
|
|
29
49
|
def start(messages)
|
|
30
50
|
super
|
|
31
51
|
|
|
32
|
-
@
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
52
|
+
@collapser.refresh!(messages.first.offset)
|
|
53
|
+
|
|
54
|
+
@filter.apply!(messages)
|
|
55
|
+
|
|
56
|
+
@executed.clear
|
|
57
|
+
|
|
58
|
+
# We keep the old processed offsets until the collapsing is done and regular processing
|
|
59
|
+
# with virtualization is restored
|
|
60
|
+
@virtual_offset_manager.clear if topic.virtual_partitions? && !@collapser.collapsed?
|
|
61
|
+
|
|
62
|
+
@last_message = messages.last
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Sets the consumer failure status and additionally starts the collapse until
|
|
66
|
+
#
|
|
67
|
+
# @param consumer [Karafka::BaseConsumer] consumer that failed
|
|
68
|
+
# @param error [StandardError] error from the failure
|
|
69
|
+
def failure!(consumer, error)
|
|
70
|
+
super
|
|
71
|
+
@collapser.collapse_until!(@last_message.offset + 1)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @return [Boolean] are we in a collapsed state at the moment
|
|
75
|
+
def collapsed?
|
|
76
|
+
@collapser.collapsed?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# @return [Boolean] did any of the filters apply any logic that would cause use to run
|
|
80
|
+
# the filtering flow
|
|
81
|
+
def filtered?
|
|
82
|
+
@filter.applied?
|
|
38
83
|
end
|
|
39
84
|
|
|
40
85
|
# @return [Boolean] is the coordinated work finished or not
|
|
@@ -42,14 +87,22 @@ module Karafka
|
|
|
42
87
|
@running_jobs.zero?
|
|
43
88
|
end
|
|
44
89
|
|
|
90
|
+
# Runs synchronized code once for a collective of virtual partitions prior to work being
|
|
91
|
+
# enqueued
|
|
92
|
+
def on_enqueued
|
|
93
|
+
@flow_lock.synchronize do
|
|
94
|
+
return unless executable?(:on_enqueued)
|
|
95
|
+
|
|
96
|
+
yield(@last_message)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
45
100
|
# Runs given code only once per all the coordinated jobs upon starting first of them
|
|
46
101
|
def on_started
|
|
47
102
|
@flow_lock.synchronize do
|
|
48
|
-
return
|
|
103
|
+
return unless executable?(:on_started)
|
|
49
104
|
|
|
50
|
-
@
|
|
51
|
-
|
|
52
|
-
yield(@first_message, @last_message)
|
|
105
|
+
yield(@last_message)
|
|
53
106
|
end
|
|
54
107
|
end
|
|
55
108
|
|
|
@@ -59,13 +112,36 @@ module Karafka
|
|
|
59
112
|
def on_finished
|
|
60
113
|
@flow_lock.synchronize do
|
|
61
114
|
return unless finished?
|
|
62
|
-
return
|
|
115
|
+
return unless executable?(:on_finished)
|
|
116
|
+
|
|
117
|
+
yield(@last_message)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
63
120
|
|
|
64
|
-
|
|
121
|
+
# Runs once after a partition is revoked
|
|
122
|
+
def on_revoked
|
|
123
|
+
@flow_lock.synchronize do
|
|
124
|
+
return unless executable?(:on_revoked)
|
|
65
125
|
|
|
66
|
-
yield(@
|
|
126
|
+
yield(@last_message)
|
|
67
127
|
end
|
|
68
128
|
end
|
|
129
|
+
|
|
130
|
+
private
|
|
131
|
+
|
|
132
|
+
# Checks if given action is executable once. If it is and true is returned, this method
|
|
133
|
+
# will return false next time it is used.
|
|
134
|
+
#
|
|
135
|
+
# @param action [Symbol] what action we want to perform
|
|
136
|
+
# @return [Boolean] true if we can
|
|
137
|
+
# @note This method needs to run behind a mutex.
|
|
138
|
+
def executable?(action)
|
|
139
|
+
return false if @executed.include?(action)
|
|
140
|
+
|
|
141
|
+
@executed << action
|
|
142
|
+
|
|
143
|
+
true
|
|
144
|
+
end
|
|
69
145
|
end
|
|
70
146
|
end
|
|
71
147
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
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 Filters
|
|
18
|
+
# Base for all the filters.
|
|
19
|
+
# All filters (including custom) need to use this API.
|
|
20
|
+
#
|
|
21
|
+
# Due to the fact, that filters can limit data in such a way, that we need to pause or
|
|
22
|
+
# seek (throttling for example), the api is not just "remove some things from batch" but
|
|
23
|
+
# also provides ways to control the post-filtering operations that may be needed.
|
|
24
|
+
class Base
|
|
25
|
+
# @return [Karafka::Messages::Message, nil] the message that we want to use as a cursor
|
|
26
|
+
# one to pause or seek or nil if not applicable.
|
|
27
|
+
attr_reader :cursor
|
|
28
|
+
|
|
29
|
+
include Karafka::Core::Helpers::Time
|
|
30
|
+
|
|
31
|
+
def initialize
|
|
32
|
+
@applied = false
|
|
33
|
+
@cursor = nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @param messages [Array<Karafka::Messages::Message>] array with messages. Please keep
|
|
37
|
+
# in mind, this may already be partial due to execution of previous filters.
|
|
38
|
+
def apply!(messages)
|
|
39
|
+
raise NotImplementedError, 'Implement in a subclass'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @return [Symbol] filter post-execution action on consumer. Either `:skip`, `:pause` or
|
|
43
|
+
# `:seek`.
|
|
44
|
+
def action
|
|
45
|
+
:skip
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [Boolean] did this filter change messages in any way
|
|
49
|
+
def applied?
|
|
50
|
+
@applied
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Integer] default timeout for pausing (if applicable)
|
|
54
|
+
def timeout
|
|
55
|
+
0
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
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 Filters
|
|
18
|
+
# A filter that allows us to delay processing by pausing until time is right.
|
|
19
|
+
class Delayer < Base
|
|
20
|
+
# @param delay [Integer] ms delay / minimum age of each message we want to process
|
|
21
|
+
def initialize(delay)
|
|
22
|
+
super()
|
|
23
|
+
|
|
24
|
+
@delay = delay
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Removes too old messages
|
|
28
|
+
#
|
|
29
|
+
# @param messages [Array<Karafka::Messages::Message>]
|
|
30
|
+
def apply!(messages)
|
|
31
|
+
@applied = false
|
|
32
|
+
@cursor = nil
|
|
33
|
+
|
|
34
|
+
# Time on message is in seconds with ms precision, so we need to convert the ttl that
|
|
35
|
+
# is in ms to this format
|
|
36
|
+
border = ::Time.now.utc - @delay / 1_000.to_f
|
|
37
|
+
|
|
38
|
+
messages.delete_if do |message|
|
|
39
|
+
too_young = message.timestamp > border
|
|
40
|
+
|
|
41
|
+
if too_young
|
|
42
|
+
@applied = true
|
|
43
|
+
|
|
44
|
+
@cursor ||= message
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
@applied
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @return [Integer] timeout delay in ms
|
|
52
|
+
def timeout
|
|
53
|
+
return 0 unless @cursor
|
|
54
|
+
|
|
55
|
+
timeout = (@delay / 1_000.to_f) - (::Time.now.utc - @cursor.timestamp)
|
|
56
|
+
|
|
57
|
+
timeout <= 0 ? 0 : timeout * 1_000
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [Symbol] action to take on post-filtering
|
|
61
|
+
def action
|
|
62
|
+
return :skip unless applied?
|
|
63
|
+
|
|
64
|
+
timeout <= 0 ? :seek : :pause
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
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 Filters
|
|
18
|
+
# Expirer for removing too old messages.
|
|
19
|
+
# It never moves offsets in any way and does not impact the processing flow. It always
|
|
20
|
+
# runs `:skip` action.
|
|
21
|
+
class Expirer < Base
|
|
22
|
+
# @param ttl [Integer] maximum age of a message (in ms)
|
|
23
|
+
def initialize(ttl)
|
|
24
|
+
super()
|
|
25
|
+
|
|
26
|
+
@ttl = ttl
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Removes too old messages
|
|
30
|
+
#
|
|
31
|
+
# @param messages [Array<Karafka::Messages::Message>]
|
|
32
|
+
def apply!(messages)
|
|
33
|
+
@applied = false
|
|
34
|
+
|
|
35
|
+
# Time on message is in seconds with ms precision, so we need to convert the ttl that
|
|
36
|
+
# is in ms to this format
|
|
37
|
+
border = ::Time.now.utc - @ttl / 1_000.to_f
|
|
38
|
+
|
|
39
|
+
messages.delete_if do |message|
|
|
40
|
+
too_old = message.timestamp < border
|
|
41
|
+
|
|
42
|
+
@applied = true if too_old
|
|
43
|
+
|
|
44
|
+
too_old
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
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
|
+
# Namespace containing Pro out of the box filters used by various strategies
|
|
18
|
+
module Filters
|
|
19
|
+
# Throttler used to limit number of messages we can process in a given time interval
|
|
20
|
+
# The tricky thing is, that even if we throttle on 100 messages, if we've reached 100, we
|
|
21
|
+
# still need to indicate, that we throttle despite not receiving 101. Otherwise we will
|
|
22
|
+
# not pause the partition and will fetch more data that we should not process.
|
|
23
|
+
#
|
|
24
|
+
# This is a special type of a filter that always throttles and makes us wait / seek if
|
|
25
|
+
# anything is applied out.
|
|
26
|
+
class Throttler < Base
|
|
27
|
+
# @param limit [Integer] how many messages we can process in a given time
|
|
28
|
+
# @param interval [Integer] interval in milliseconds for which we want to process
|
|
29
|
+
def initialize(limit, interval)
|
|
30
|
+
super()
|
|
31
|
+
|
|
32
|
+
@limit = limit
|
|
33
|
+
@interval = interval
|
|
34
|
+
@requests = Hash.new { |h, k| h[k] = 0 }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Limits number of messages to a range that we can process (if needed) and keeps track
|
|
38
|
+
# of how many messages we've processed in a given time
|
|
39
|
+
# @param messages [Array<Karafka::Messages::Message>] limits the number of messages to
|
|
40
|
+
# number we can accept in the context of throttling constraints
|
|
41
|
+
def apply!(messages)
|
|
42
|
+
@applied = false
|
|
43
|
+
@cursor = nil
|
|
44
|
+
@time = monotonic_now
|
|
45
|
+
@requests.delete_if { |timestamp, _| timestamp < (@time - @interval) }
|
|
46
|
+
values = @requests.values.sum
|
|
47
|
+
accepted = 0
|
|
48
|
+
|
|
49
|
+
messages.delete_if do |message|
|
|
50
|
+
# +1 because of current
|
|
51
|
+
@applied = (values + accepted + 1) > @limit
|
|
52
|
+
|
|
53
|
+
@cursor = message if @applied && @cursor.nil?
|
|
54
|
+
|
|
55
|
+
next true if @applied
|
|
56
|
+
|
|
57
|
+
accepted += 1
|
|
58
|
+
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
@requests[@time] += accepted
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# @return [Symbol] action to take upon throttler reaching certain state
|
|
66
|
+
def action
|
|
67
|
+
if applied?
|
|
68
|
+
timeout.zero? ? :seek : :pause
|
|
69
|
+
else
|
|
70
|
+
:skip
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @return [Integer] minimum number of milliseconds to wait before getting more messages
|
|
75
|
+
# so we are no longer throttled and so we can process at least one message
|
|
76
|
+
def timeout
|
|
77
|
+
timeout = @interval - (monotonic_now - @time)
|
|
78
|
+
timeout <= 0 ? 0 : timeout
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
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 Filters
|
|
18
|
+
# Removes messages that are already marked as consumed in the virtual offset manager
|
|
19
|
+
# This should operate only when using virtual partitions.
|
|
20
|
+
#
|
|
21
|
+
# This cleaner prevents us from duplicated processing of messages that were virtually
|
|
22
|
+
# marked as consumed even if we could not mark them as consumed in Kafka. This allows us
|
|
23
|
+
# to limit reprocessing when errors occur drastically when operating with virtual
|
|
24
|
+
# partitions
|
|
25
|
+
#
|
|
26
|
+
# @note It should be registered only when VPs are used
|
|
27
|
+
class VirtualLimiter < Base
|
|
28
|
+
# @param manager [Processing::VirtualOffsetManager]
|
|
29
|
+
# @param collapser [Processing::Collapser]
|
|
30
|
+
def initialize(manager, collapser)
|
|
31
|
+
@manager = manager
|
|
32
|
+
@collapser = collapser
|
|
33
|
+
|
|
34
|
+
super()
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Remove messages that we already marked as virtually consumed. Does nothing if not in
|
|
38
|
+
# the collapsed mode.
|
|
39
|
+
#
|
|
40
|
+
# @param messages [Array<Karafka::Messages::Message>]
|
|
41
|
+
def apply!(messages)
|
|
42
|
+
return unless @collapser.collapsed?
|
|
43
|
+
|
|
44
|
+
marked = @manager.marked
|
|
45
|
+
|
|
46
|
+
messages.delete_if { |message| marked.include?(message.offset) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
# Applier for all filters we want to have. Whether related to limiting messages based
|
|
18
|
+
# on the payload or any other things.
|
|
19
|
+
#
|
|
20
|
+
# From the outside world perspective, this encapsulates all the filters.
|
|
21
|
+
# This means that this is the API we expose as a single filter, allowing us to control
|
|
22
|
+
# the filtering via many filters easily.
|
|
23
|
+
class FiltersApplier
|
|
24
|
+
# @return [Array] registered filters array. Useful if we want to inject internal context
|
|
25
|
+
# aware filters.
|
|
26
|
+
attr_reader :filters
|
|
27
|
+
|
|
28
|
+
# @param coordinator [Pro::Coordinator] pro coordinator
|
|
29
|
+
def initialize(coordinator)
|
|
30
|
+
# Builds filters out of their factories
|
|
31
|
+
# We build it that way (providing topic and partition) because there may be a case where
|
|
32
|
+
# someone wants to have a specific logic that is per topic or partition. Like for example
|
|
33
|
+
# a case where there is a cache bypassing revocations for topic partition.
|
|
34
|
+
#
|
|
35
|
+
# We provide full Karafka routing topic here and not the name only, in case the filter
|
|
36
|
+
# would be customized based on other topic settings (like VPs, etc)
|
|
37
|
+
#
|
|
38
|
+
# This setup allows for biggest flexibility also because topic object holds the reference
|
|
39
|
+
# to the subscription group and consumer group
|
|
40
|
+
@filters = coordinator.topic.filtering.factories.map do |factory|
|
|
41
|
+
factory.call(coordinator.topic, coordinator.partition)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param messages [Array<Karafka::Messages::Message>] array with messages from the
|
|
46
|
+
# partition
|
|
47
|
+
def apply!(messages)
|
|
48
|
+
return unless active?
|
|
49
|
+
|
|
50
|
+
@filters.each { |filter| filter.apply!(messages) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [Boolean] did we filter out any messages during filtering run
|
|
54
|
+
def applied?
|
|
55
|
+
return false unless active?
|
|
56
|
+
|
|
57
|
+
!applied.empty?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [Symbol] consumer post-filtering action that should be taken
|
|
61
|
+
def action
|
|
62
|
+
return :skip unless applied?
|
|
63
|
+
|
|
64
|
+
# The highest priority is on a potential backoff from any of the filters because it is
|
|
65
|
+
# the less risky (delay and continue later)
|
|
66
|
+
return :pause if applied.any? { |filter| filter.action == :pause }
|
|
67
|
+
|
|
68
|
+
# If none of the filters wanted to pause, we can check for any that would want to seek
|
|
69
|
+
# and if there is any, we can go with this strategy
|
|
70
|
+
return :seek if applied.any? { |filter| filter.action == :seek }
|
|
71
|
+
|
|
72
|
+
:skip
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# @return [Integer] minimum timeout we need to pause. This is the minimum for all the
|
|
76
|
+
# filters to satisfy all of them.
|
|
77
|
+
def timeout
|
|
78
|
+
applied.map(&:timeout).compact.min || 0
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# The first message we do need to get next time we poll. We use the minimum not to jump
|
|
82
|
+
# accidentally by over any.
|
|
83
|
+
# @return [Karafka::Messages::Message, nil] cursor message or nil if none
|
|
84
|
+
def cursor
|
|
85
|
+
return nil unless active?
|
|
86
|
+
|
|
87
|
+
applied.map(&:cursor).compact.min_by(&:offset)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
# @return [Boolean] is filtering active
|
|
93
|
+
def active?
|
|
94
|
+
!@filters.empty?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @return [Array<Object>] filters that applied any sort of messages limiting
|
|
98
|
+
def applied
|
|
99
|
+
@filters.select(&:applied?)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
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
|
#
|
|
@@ -16,8 +18,7 @@ module Karafka
|
|
|
16
18
|
# Pro jobs
|
|
17
19
|
module Jobs
|
|
18
20
|
# The main job type in a non-blocking variant.
|
|
19
|
-
# This variant works "like" the regular consumption but
|
|
20
|
-
# as it is needed until a job is done.
|
|
21
|
+
# This variant works "like" the regular consumption but does not block the queue.
|
|
21
22
|
#
|
|
22
23
|
# It can be useful when having long lasting jobs that would exceed `max.poll.interval`
|
|
23
24
|
# if would block.
|
|
@@ -25,8 +26,9 @@ module Karafka
|
|
|
25
26
|
# @note It needs to be working with a proper consumer that will handle the partition
|
|
26
27
|
# management. This layer of the framework knows nothing about Kafka messages consumption.
|
|
27
28
|
class ConsumeNonBlocking < ::Karafka::Processing::Jobs::Consume
|
|
28
|
-
#
|
|
29
|
-
|
|
29
|
+
# Makes this job non-blocking from the start
|
|
30
|
+
# @param args [Array] any arguments accepted by `::Karafka::Processing::Jobs::Consume`
|
|
31
|
+
def initialize(*args)
|
|
30
32
|
super
|
|
31
33
|
@non_blocking = true
|
|
32
34
|
end
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
# Pro components related to processing part of Karafka
|
|
17
|
+
module Processing
|
|
18
|
+
# Pro jobs
|
|
19
|
+
module Jobs
|
|
20
|
+
# The revoked job type in a non-blocking variant.
|
|
21
|
+
# This variant works "like" the regular revoked but does not block the queue.
|
|
22
|
+
#
|
|
23
|
+
# It can be useful when having long lasting jobs that would exceed `max.poll.interval`
|
|
24
|
+
# in scenarios where there are more jobs than threads, without this being async we
|
|
25
|
+
# would potentially stop polling
|
|
26
|
+
class RevokedNonBlocking < ::Karafka::Processing::Jobs::Revoked
|
|
27
|
+
# Makes this job non-blocking from the start
|
|
28
|
+
# @param args [Array] any arguments accepted by `::Karafka::Processing::Jobs::Revoked`
|
|
29
|
+
def initialize(*args)
|
|
30
|
+
super
|
|
31
|
+
@non_blocking = true
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
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
|
#
|
|
@@ -14,14 +16,30 @@ module Karafka
|
|
|
14
16
|
module Processing
|
|
15
17
|
# Pro jobs builder that supports lrj
|
|
16
18
|
class JobsBuilder < ::Karafka::Processing::JobsBuilder
|
|
19
|
+
# @param executor [Karafka::Processing::Executor]
|
|
20
|
+
def idle(executor)
|
|
21
|
+
Karafka::Processing::Jobs::Idle.new(executor)
|
|
22
|
+
end
|
|
23
|
+
|
|
17
24
|
# @param executor [Karafka::Processing::Executor]
|
|
18
25
|
# @param messages [Karafka::Messages::Messages] messages batch to be consumed
|
|
19
|
-
# @param coordinator [Karafka::Processing::Coordinator]
|
|
20
26
|
# @return [Karafka::Processing::Jobs::Consume] blocking job
|
|
21
27
|
# @return [Karafka::Pro::Processing::Jobs::ConsumeNonBlocking] non blocking for lrj
|
|
22
|
-
def consume(executor, messages
|
|
28
|
+
def consume(executor, messages)
|
|
29
|
+
if executor.topic.long_running_job?
|
|
30
|
+
Jobs::ConsumeNonBlocking.new(executor, messages)
|
|
31
|
+
else
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @param executor [Karafka::Processing::Executor]
|
|
37
|
+
# @return [Karafka::Processing::Jobs::Revoked] revocation job for non LRJ
|
|
38
|
+
# @return [Karafka::Processing::Jobs::RevokedNonBlocking] revocation job that is
|
|
39
|
+
# non-blocking, so when revocation job is scheduled for LRJ it also will not block
|
|
40
|
+
def revoked(executor)
|
|
23
41
|
if executor.topic.long_running_job?
|
|
24
|
-
Jobs::
|
|
42
|
+
Jobs::RevokedNonBlocking.new(executor)
|
|
25
43
|
else
|
|
26
44
|
super
|
|
27
45
|
end
|