karafka 2.6.0.beta1 → 2.6.0.rc2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -27
- data/certs/expired.txt +2 -0
- data/config/locales/errors.yml +5 -0
- data/config/locales/pro_errors.yml +5 -5
- data/karafka.gemspec +1 -1
- data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -1
- data/lib/karafka/active_job/current_attributes/loading.rb +1 -1
- data/lib/karafka/active_job/current_attributes.rb +4 -2
- data/lib/karafka/active_job/dispatcher.rb +1 -2
- data/lib/karafka/admin/consumer_groups.rb +8 -2
- data/lib/karafka/admin/replication.rb +6 -3
- data/lib/karafka/admin/topics.rb +32 -12
- data/lib/karafka/admin.rb +155 -59
- data/lib/karafka/app.rb +1 -1
- data/lib/karafka/base_consumer.rb +33 -5
- data/lib/karafka/cli/console.rb +0 -1
- data/lib/karafka/cli/help.rb +0 -1
- data/lib/karafka/cli/info.rb +0 -1
- data/lib/karafka/cli/install.rb +0 -1
- data/lib/karafka/cli/server.rb +0 -1
- data/lib/karafka/cli/swarm.rb +0 -1
- data/lib/karafka/cli.rb +2 -2
- data/lib/karafka/connection/client.rb +44 -7
- data/lib/karafka/connection/listener.rb +3 -3
- data/lib/karafka/connection/manager.rb +0 -1
- data/lib/karafka/connection/pauses_manager.rb +20 -3
- data/lib/karafka/connection/proxy.rb +45 -0
- data/lib/karafka/connection/status.rb +0 -1
- data/lib/karafka/instrumentation/assignments_tracker.rb +34 -0
- data/lib/karafka/instrumentation/callbacks/consumer_groups/decorator.rb +19 -0
- data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +0 -1
- data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +3 -2
- data/lib/karafka/instrumentation/critical_errors_listener.rb +85 -0
- data/lib/karafka/instrumentation/logger_listener.rb +2 -0
- data/lib/karafka/instrumentation/monitor.rb +2 -3
- data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +0 -1
- data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +0 -1
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +4 -3
- data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +0 -2
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +181 -18
- data/lib/karafka/pro/admin/recovery/errors.rb +0 -1
- data/lib/karafka/pro/admin/recovery.rb +6 -4
- data/lib/karafka/pro/base_consumer.rb +5 -5
- data/lib/karafka/pro/cleaner/messages/metadata.rb +0 -1
- data/lib/karafka/pro/cli/parallel_segments/base.rb +1 -2
- data/lib/karafka/pro/connection/manager.rb +7 -4
- data/lib/karafka/pro/encryption/messages/middleware.rb +5 -0
- data/lib/karafka/pro/encryption/messages/parser.rb +4 -0
- data/lib/karafka/pro/instrumentation/callbacks/consumer_groups/decorator.rb +63 -0
- data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/compensator.rb +120 -0
- data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/fetcher.rb +88 -0
- data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/refresher.rb +185 -0
- data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/registry.rb +102 -0
- data/lib/karafka/pro/instrumentation/performance_tracker.rb +40 -6
- data/lib/karafka/pro/iterator/tpl_builder.rb +27 -7
- data/lib/karafka/pro/iterator.rb +22 -7
- data/lib/karafka/pro/loader.rb +12 -0
- data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +2 -4
- data/lib/karafka/pro/processing/consumer_groups/collapser.rb +6 -9
- data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +1 -4
- data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +21 -10
- data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +4 -4
- data/lib/karafka/pro/processing/consumer_groups/expansions_selector.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/filters/actions.rb +84 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +5 -6
- data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +1 -4
- data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +1 -4
- data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/jobs/consume_non_blocking.rb +2 -3
- data/lib/karafka/pro/processing/consumer_groups/jobs/eofed_non_blocking.rb +0 -2
- data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +2 -3
- data/lib/karafka/pro/processing/consumer_groups/jobs/periodic_non_blocking.rb +0 -2
- data/lib/karafka/pro/processing/consumer_groups/jobs/revoked_non_blocking.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +5 -4
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +3 -7
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +8 -10
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +3 -5
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +10 -9
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +11 -10
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom.rb +8 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +9 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +5 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom.rb +4 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +6 -9
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom.rb +3 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +4 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +4 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/base.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +56 -33
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +27 -14
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +4 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +5 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb +5 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +3 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom_vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom_vp.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +65 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +0 -4
- data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/vp.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +4 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +4 -8
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +3 -6
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +3 -7
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/vp.rb +2 -5
- data/lib/karafka/pro/processing/consumer_groups/strategies/mom/default.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr_vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/mom/vp.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +11 -6
- data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +0 -3
- data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +2 -4
- data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/consistent.rb +0 -3
- data/lib/karafka/pro/processing/jobs_queue.rb +4 -1
- data/lib/karafka/pro/processing/schedulers/base.rb +4 -2
- data/lib/karafka/pro/processing/schedulers/default.rb +2 -2
- data/lib/karafka/pro/recurring_tasks/consumer.rb +9 -2
- data/lib/karafka/pro/recurring_tasks/contracts/config.rb +0 -1
- data/lib/karafka/pro/recurring_tasks/executor.rb +25 -13
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +0 -2
- data/lib/karafka/pro/routing/features/consumer_groups/long_running_job.rb +0 -2
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/proxy.rb +2 -2
- data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job.rb +0 -2
- data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +0 -6
- data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +5 -4
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/config.rb +0 -6
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +2 -1
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/pattern.rb +0 -1
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +2 -1
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +2 -1
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +8 -8
- data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +5 -5
- data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +34 -15
- data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +52 -28
- data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +2 -1
- data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +6 -5
- data/lib/karafka/pro/routing/features/pausing/config.rb +7 -11
- data/lib/karafka/pro/routing/features/pausing/contracts/topic.rb +6 -8
- data/lib/karafka/pro/routing/features/pausing/topic.rb +18 -63
- data/lib/karafka/pro/scheduled_messages/consumer.rb +7 -1
- data/lib/karafka/pro/scheduled_messages/schema_validator.rb +6 -1
- data/lib/karafka/pro/swarm/liveness_listener.rb +118 -13
- data/lib/karafka/pro.rb +0 -6
- data/lib/karafka/processing/consumer_groups/coordinator.rb +4 -5
- data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +6 -2
- data/lib/karafka/processing/consumer_groups/executor.rb +4 -4
- data/lib/karafka/processing/consumer_groups/executors_buffer.rb +2 -4
- data/lib/karafka/processing/consumer_groups/expansions_selector.rb +0 -2
- data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +0 -2
- data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +0 -2
- data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +14 -16
- data/lib/karafka/processing/consumer_groups/jobs/consume.rb +2 -5
- data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +2 -3
- data/lib/karafka/processing/consumer_groups/jobs/idle.rb +2 -2
- data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +2 -4
- data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +2 -2
- data/lib/karafka/processing/consumer_groups/partitioner.rb +3 -6
- data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +5 -2
- data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +2 -4
- data/lib/karafka/processing/consumer_groups/strategies/base.rb +3 -5
- data/lib/karafka/processing/consumer_groups/strategies/default.rb +43 -13
- data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +5 -2
- data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +5 -2
- data/lib/karafka/processing/consumer_groups/strategies/mom.rb +2 -3
- data/lib/karafka/processing/consumer_groups/strategy_selector.rb +0 -2
- data/lib/karafka/processing/coordinator.rb +0 -2
- data/lib/karafka/processing/coordinators_buffer.rb +0 -2
- data/lib/karafka/processing/partitioner.rb +0 -2
- data/lib/karafka/processing/strategy_selector.rb +0 -2
- data/lib/karafka/processing/worker.rb +14 -6
- data/lib/karafka/processing/workers_pool.rb +21 -4
- data/lib/karafka/railtie.rb +0 -1
- data/lib/karafka/routing/contracts/routing.rb +2 -2
- data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +6 -5
- data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +2 -2
- data/lib/karafka/routing/features/deserializers/topic.rb +0 -1
- data/lib/karafka/routing/features/pausing/config.rb +27 -0
- data/lib/karafka/routing/features/pausing.rb +13 -0
- data/lib/karafka/routing/subscription_group.rb +1 -1
- data/lib/karafka/routing/topic.rb +20 -7
- data/lib/karafka/routing/topics.rb +21 -1
- data/lib/karafka/server.rb +9 -0
- data/lib/karafka/setup/config.rb +52 -55
- data/lib/karafka/setup/config_proxy.rb +2 -1
- data/lib/karafka/setup/contracts/config.rb +14 -0
- data/lib/karafka/swarm/node.rb +2 -2
- data/lib/karafka/version.rb +1 -2
- data/lib/karafka.rb +2 -2
- metadata +14 -4
|
@@ -50,12 +50,13 @@ module Karafka
|
|
|
50
50
|
# groups that will be created)
|
|
51
51
|
# @param partitioner [nil, #call] nil or callable partitioner
|
|
52
52
|
# @param reducer [nil, #call] reducer for parallel key. It allows for using a custom
|
|
53
|
-
# reducer to achieve enhanced parallelization when the default reducer is not
|
|
53
|
+
# reducer to achieve enhanced parallelization when the default reducer is not
|
|
54
|
+
# enough.
|
|
54
55
|
# @param merge_key [String] key used to build the parallel segment consumer groups
|
|
55
56
|
#
|
|
56
|
-
# @note This method is an assignor but the API is actually via the
|
|
57
|
-
# method. Our `Routing::Proxy` normalizes that the way we want
|
|
58
|
-
# for the end users.
|
|
57
|
+
# @note This method is an assignor but the API is actually via the
|
|
58
|
+
# `#parallel_segments` method. Our `Routing::Proxy` normalizes that the way we want
|
|
59
|
+
# to have it exposed for the end users.
|
|
59
60
|
def parallel_segments=(
|
|
60
61
|
count: 1,
|
|
61
62
|
partitioner: nil,
|
|
@@ -33,12 +33,6 @@ module Karafka
|
|
|
33
33
|
module Routing
|
|
34
34
|
module Features
|
|
35
35
|
module ConsumerGroups
|
|
36
|
-
# Holds pattern info reference
|
|
37
|
-
# Type is set to:
|
|
38
|
-
# `:regular` - in case patterns are not used and topic is just a regular existing topic
|
|
39
|
-
# matched directly based on the name
|
|
40
|
-
# `:discovered` - in case it is a real topic on which we started to listed
|
|
41
|
-
# `:matcher` - represents a regular expression used by librdkafka
|
|
42
36
|
class Patterns < Base
|
|
43
37
|
# Config for pattern based topic Only pattern related topics are active in this context
|
|
44
38
|
Config = Struct.new(
|
|
@@ -42,7 +42,8 @@ module Karafka
|
|
|
42
42
|
@patterns = Patterns.new([])
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
# @return [::Karafka::Pro::Routing::Features::ConsumerGroups::Patterns::Patterns]
|
|
45
|
+
# @return [::Karafka::Pro::Routing::Features::ConsumerGroups::Patterns::Patterns]
|
|
46
|
+
# created patterns
|
|
46
47
|
def patterns
|
|
47
48
|
@patterns
|
|
48
49
|
end
|
|
@@ -71,7 +71,8 @@ module Karafka
|
|
|
71
71
|
|
|
72
72
|
# Adds the discovered topic into the routing
|
|
73
73
|
#
|
|
74
|
-
# @param pattern [Karafka::Pro::Routing::Features::ConsumerGroups::Patterns::Pattern]
|
|
74
|
+
# @param pattern [Karafka::Pro::Routing::Features::ConsumerGroups::Patterns::Pattern]
|
|
75
|
+
# matched pattern
|
|
75
76
|
# @param discovered_topic [String] topic that we discovered that should be part of the
|
|
76
77
|
# routing from now on.
|
|
77
78
|
# @param sg_topics [Array<Karafka::Routing::Topic>]
|
|
@@ -100,7 +100,8 @@ module Karafka
|
|
|
100
100
|
# prevent it from running but internally in this component we need to ensure, that
|
|
101
101
|
# prior to the validations we operate on a regexp
|
|
102
102
|
#
|
|
103
|
-
# @return [Regexp] returns a regexp always even if what we've received was not a
|
|
103
|
+
# @return [Regexp] returns a regexp always even if what we've received was not a
|
|
104
|
+
# regexp
|
|
104
105
|
def safe_regexp
|
|
105
106
|
# This regexp will never match anything
|
|
106
107
|
regexp.is_a?(Regexp) ? regexp : /$a/
|
|
@@ -47,15 +47,15 @@ module Karafka
|
|
|
47
47
|
#
|
|
48
48
|
# @param topic_name [String] topic name
|
|
49
49
|
# @return [Karafka::Routing::Topic]
|
|
50
|
-
# @raise [Karafka::Errors::TopicNotFoundError] this should never happen. If you see
|
|
51
|
-
# please create an issue.
|
|
50
|
+
# @raise [Karafka::Errors::TopicNotFoundError] this should never happen. If you see
|
|
51
|
+
# it, please create an issue.
|
|
52
52
|
#
|
|
53
|
-
# @note This method should not be used in context of finding multiple missing topics
|
|
54
|
-
# loops because it catches exceptions and attempts to expand routes. If this is
|
|
55
|
-
# in a loop for lookups on thousands of topics with detector expansion, this
|
|
56
|
-
# be slow. It should be used in the context where newly discovered topics are
|
|
57
|
-
# and should by design match a pattern. For quick lookups on batches of
|
|
58
|
-
# is recommended to use a custom built lookup with conditional expander.
|
|
53
|
+
# @note This method should not be used in context of finding multiple missing topics
|
|
54
|
+
# in loops because it catches exceptions and attempts to expand routes. If this is
|
|
55
|
+
# used in a loop for lookups on thousands of topics with detector expansion, this
|
|
56
|
+
# may be slow. It should be used in the context where newly discovered topics are
|
|
57
|
+
# found and should by design match a pattern. For quick lookups on batches of
|
|
58
|
+
# topics, it is recommended to use a custom built lookup with conditional expander.
|
|
59
59
|
def find(topic_name)
|
|
60
60
|
super
|
|
61
61
|
rescue Karafka::Errors::TopicNotFoundError
|
|
@@ -49,12 +49,12 @@ module Karafka
|
|
|
49
49
|
# poll where messages were not received.
|
|
50
50
|
# @param active [Boolean] should ticking happen for this topic assignments.
|
|
51
51
|
# @param interval [Integer] minimum interval to run periodic jobs on given topic.
|
|
52
|
-
# @param during_pause [Boolean, nil] Should periodic jobs run when partition is
|
|
53
|
-
# It is set to `nil` by default allowing for detection when this value is
|
|
54
|
-
# configured but should be built dynamically based on LRJ status.
|
|
52
|
+
# @param during_pause [Boolean, nil] Should periodic jobs run when partition is
|
|
53
|
+
# paused. It is set to `nil` by default allowing for detection when this value is
|
|
54
|
+
# not configured but should be built dynamically based on LRJ status.
|
|
55
55
|
# @param during_retry [Boolean, nil] Should we run when there was an error and we are
|
|
56
|
-
# in a retry flow. Please note that for this to work, `during_pause` also needs to
|
|
57
|
-
# set to true as errors retry happens after pause.
|
|
56
|
+
# in a retry flow. Please note that for this to work, `during_pause` also needs to
|
|
57
|
+
# be set to true as errors retry happens after pause.
|
|
58
58
|
def periodic_job(
|
|
59
59
|
active = false,
|
|
60
60
|
interval: nil,
|
|
@@ -52,6 +52,39 @@ module Karafka
|
|
|
52
52
|
tasks_cfg = App.config.recurring_tasks
|
|
53
53
|
topics_cfg = tasks_cfg.topics
|
|
54
54
|
|
|
55
|
+
# Declarative topic definitions live independently of routing. We declare the
|
|
56
|
+
# broker-side structure here so it is managed by the CLI topics commands without
|
|
57
|
+
# relying on the (to be retired) routing `config(...)` bridge.
|
|
58
|
+
#
|
|
59
|
+
# We guard each declaration with `find_topic` because `Declaratives::Builder#topic`
|
|
60
|
+
# re-applies its block on an already existing declaration (additive semantics),
|
|
61
|
+
# unlike the old bridge which used `||=` and kept the first declaration. Without the
|
|
62
|
+
# guard, our framework defaults would clobber a topic the user may have declared
|
|
63
|
+
# themselves via `App.declaratives.draw`. Skipping when already present preserves
|
|
64
|
+
# first-declaration-wins.
|
|
65
|
+
App.declaratives.draw do
|
|
66
|
+
# Keep older data for a day and compact to the last state available
|
|
67
|
+
unless find_topic(topics_cfg.schedules.name)
|
|
68
|
+
topic(topics_cfg.schedules.name) do
|
|
69
|
+
config(
|
|
70
|
+
"cleanup.policy": "compact,delete",
|
|
71
|
+
"retention.ms": 86_400_000
|
|
72
|
+
)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Keep cron logs of executions for a week and after that remove. Week should be
|
|
77
|
+
# enough and should not produce too much data.
|
|
78
|
+
unless find_topic(topics_cfg.logs.name)
|
|
79
|
+
topic(topics_cfg.logs.name) do
|
|
80
|
+
config(
|
|
81
|
+
"cleanup.policy": "delete",
|
|
82
|
+
"retention.ms": 604_800_000
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
55
88
|
consumer_group tasks_cfg.group_id do
|
|
56
89
|
# Registers the primary topic that we use to control schedules execution. This is
|
|
57
90
|
# the one that we use to trigger recurring tasks.
|
|
@@ -84,14 +117,7 @@ module Karafka
|
|
|
84
117
|
# Since the execution of particular tasks is isolated and guarded, it should not
|
|
85
118
|
# leak. This means, that this is to handle errors like schedule version
|
|
86
119
|
# incompatibility and other errors that will not go away without a redeployment
|
|
87
|
-
|
|
88
|
-
pause_max_timeout(60 * 1_000)
|
|
89
|
-
|
|
90
|
-
# Keep older data for a day and compact to the last state available
|
|
91
|
-
config(
|
|
92
|
-
"cleanup.policy": "compact,delete",
|
|
93
|
-
"retention.ms": 86_400_000
|
|
94
|
-
)
|
|
120
|
+
pause(timeout: 60 * 1_000, max_timeout: 60 * 1_000)
|
|
95
121
|
|
|
96
122
|
# This is the core of execution. Since we're producers of states, we need a way
|
|
97
123
|
# to tick without having new data
|
|
@@ -113,13 +139,6 @@ module Karafka
|
|
|
113
139
|
active(false)
|
|
114
140
|
deserializer tasks_cfg.deserializer
|
|
115
141
|
target.recurring_tasks(true)
|
|
116
|
-
|
|
117
|
-
# Keep cron logs of executions for a week and after that remove. Week should be
|
|
118
|
-
# enough and should not produce too much data.
|
|
119
|
-
config(
|
|
120
|
-
"cleanup.policy": "delete",
|
|
121
|
-
"retention.ms": 604_800_000
|
|
122
|
-
)
|
|
123
142
|
end
|
|
124
143
|
|
|
125
144
|
yield(schedules_topic, logs_topic) if block && block.arity.positive?
|
|
@@ -38,9 +38,9 @@ module Karafka
|
|
|
38
38
|
module Builder
|
|
39
39
|
# Enabled scheduled messages operations and adds needed topics and other stuff.
|
|
40
40
|
#
|
|
41
|
-
# @param topic_name [String, false] name for scheduled messages topic that is also
|
|
42
|
-
# as a group identifier. Users can have multiple schedule topics flows to
|
|
43
|
-
# collisions, prioritize and do other stuff. `false` if not active.
|
|
41
|
+
# @param topic_name [String, false] name for scheduled messages topic that is also
|
|
42
|
+
# used as a group identifier. Users can have multiple schedule topics flows to
|
|
43
|
+
# prevent key collisions, prioritize and do other stuff. `false` if not active.
|
|
44
44
|
# @param block [Proc] optional reconfiguration of the topics definitions.
|
|
45
45
|
# @note Namespace for topics should include the divider as it is not automatically
|
|
46
46
|
# added.
|
|
@@ -54,6 +54,54 @@ module Karafka
|
|
|
54
54
|
# should have same partition count.
|
|
55
55
|
default_partitions = 5
|
|
56
56
|
msg_cfg = App.config.scheduled_messages
|
|
57
|
+
states_topic_name = "#{topic_name}#{msg_cfg.states_postfix}"
|
|
58
|
+
|
|
59
|
+
# Declarative topic definitions live independently of routing. We declare the
|
|
60
|
+
# broker-side structure here so it is managed by the CLI topics commands without
|
|
61
|
+
# relying on the (to be retired) routing `config(...)` bridge.
|
|
62
|
+
#
|
|
63
|
+
# We guard each declaration with `find_topic` because `Declaratives::Builder#topic`
|
|
64
|
+
# re-applies its block on an already existing declaration (additive semantics),
|
|
65
|
+
# unlike the old bridge which used `||=` and kept the first declaration. Without the
|
|
66
|
+
# guard, our framework defaults would clobber a topic the user may have declared
|
|
67
|
+
# themselves via `App.declaratives.draw`. Skipping when already present preserves
|
|
68
|
+
# first-declaration-wins.
|
|
69
|
+
App.declaratives.draw do
|
|
70
|
+
# This is a setup that should allow messages to be compacted fairly fast. Since
|
|
71
|
+
# each dispatched message should be removed via tombstone, they do not have to
|
|
72
|
+
# be present in the topic for too long.
|
|
73
|
+
unless find_topic(topic_name)
|
|
74
|
+
topic(topic_name) do
|
|
75
|
+
partitions default_partitions
|
|
76
|
+
config(
|
|
77
|
+
# Will ensure, that after tombstone is present, given scheduled message,
|
|
78
|
+
# that has been dispatched is removed by Kafka
|
|
79
|
+
"cleanup.policy": "compact",
|
|
80
|
+
# When 10% or more dispatches are done, compact data
|
|
81
|
+
"min.cleanable.dirty.ratio": 0.1,
|
|
82
|
+
# Frequent segment rotation to support intense compaction
|
|
83
|
+
"segment.ms": 3_600_000,
|
|
84
|
+
"delete.retention.ms": 3_600_000,
|
|
85
|
+
"segment.bytes": 52_428_800
|
|
86
|
+
)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Holds states of scheduler per each of the partitions. Same partition count as
|
|
91
|
+
# the messages topic since they tick independently per partition.
|
|
92
|
+
unless find_topic(states_topic_name)
|
|
93
|
+
topic(states_topic_name) do
|
|
94
|
+
partitions default_partitions
|
|
95
|
+
config(
|
|
96
|
+
"cleanup.policy": "compact",
|
|
97
|
+
"min.cleanable.dirty.ratio": 0.1,
|
|
98
|
+
"segment.ms": 3_600_000,
|
|
99
|
+
"delete.retention.ms": 3_600_000,
|
|
100
|
+
"segment.bytes": 52_428_800
|
|
101
|
+
)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
57
105
|
|
|
58
106
|
consumer_group msg_cfg.group_id do
|
|
59
107
|
# Registers the primary topic that we use to control schedules execution. This is
|
|
@@ -93,22 +141,6 @@ module Karafka
|
|
|
93
141
|
|
|
94
142
|
max_wait_time(1_000)
|
|
95
143
|
|
|
96
|
-
# This is a setup that should allow messages to be compacted fairly fast. Since
|
|
97
|
-
# each dispatched message should be removed via tombstone, they do not have to
|
|
98
|
-
# be present in the topic for too long.
|
|
99
|
-
config(
|
|
100
|
-
partitions: default_partitions,
|
|
101
|
-
# Will ensure, that after tombstone is present, given scheduled message, that
|
|
102
|
-
# has been dispatched is removed by Kafka
|
|
103
|
-
"cleanup.policy": "compact",
|
|
104
|
-
# When 10% or more dispatches are done, compact data
|
|
105
|
-
"min.cleanable.dirty.ratio": 0.1,
|
|
106
|
-
# Frequent segment rotation to support intense compaction
|
|
107
|
-
"segment.ms": 3_600_000,
|
|
108
|
-
"delete.retention.ms": 3_600_000,
|
|
109
|
-
"segment.bytes": 52_428_800
|
|
110
|
-
)
|
|
111
|
-
|
|
112
144
|
# This is the core of execution. Since we dispatch data in time intervals, we
|
|
113
145
|
# need to be able to do this even when no new data is coming
|
|
114
146
|
periodic(
|
|
@@ -126,17 +158,9 @@ module Karafka
|
|
|
126
158
|
# Holds states of scheduler per each of the partitions since they tick
|
|
127
159
|
# independently. We only hold future statistics not to have to deal with
|
|
128
160
|
# any type of state restoration
|
|
129
|
-
states_topic = topic(
|
|
161
|
+
states_topic = topic(states_topic_name) do
|
|
130
162
|
active(false)
|
|
131
163
|
target.scheduled_messages(true)
|
|
132
|
-
config(
|
|
133
|
-
partitions: default_partitions,
|
|
134
|
-
"cleanup.policy": "compact",
|
|
135
|
-
"min.cleanable.dirty.ratio": 0.1,
|
|
136
|
-
"segment.ms": 3_600_000,
|
|
137
|
-
"delete.retention.ms": 3_600_000,
|
|
138
|
-
"segment.bytes": 52_428_800
|
|
139
|
-
)
|
|
140
164
|
deserializers(
|
|
141
165
|
payload: msg_cfg.deserializers.payload
|
|
142
166
|
)
|
|
@@ -46,7 +46,8 @@ module Karafka
|
|
|
46
46
|
super
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
# @param active [Boolean] should this topic be considered related to scheduled
|
|
49
|
+
# @param active [Boolean] should this topic be considered related to scheduled
|
|
50
|
+
# messages
|
|
50
51
|
def scheduled_messages(active = false)
|
|
51
52
|
@scheduled_messages ||= Config.new(active: active)
|
|
52
53
|
end
|
|
@@ -45,16 +45,17 @@ module Karafka
|
|
|
45
45
|
super
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
# @param max_partitions [Integer] max number of virtual partitions that can come out
|
|
49
|
-
# the single distribution flow. When set to more than the Karafka threading, will
|
|
48
|
+
# @param max_partitions [Integer] max number of virtual partitions that can come out
|
|
49
|
+
# of the single distribution flow. When set to more than the Karafka threading, will
|
|
50
50
|
# create more work than workers. When less, can ensure we have spare resources to
|
|
51
51
|
# process other things in parallel.
|
|
52
52
|
# @param partitioner [nil, #call] nil or callable partitioner
|
|
53
53
|
# @param offset_metadata_strategy [Symbol] how we should match the metadata for the
|
|
54
|
-
# offset. `:exact` will match the offset matching metadata and `:current` will
|
|
55
|
-
# the most recently reported metadata
|
|
54
|
+
# offset. `:exact` will match the offset matching metadata and `:current` will
|
|
55
|
+
# select the most recently reported metadata
|
|
56
56
|
# @param reducer [nil, #call] reducer for VPs key. It allows for using a custom
|
|
57
|
-
# reducer to achieve enhanced parallelization when the default reducer is not
|
|
57
|
+
# reducer to achieve enhanced parallelization when the default reducer is not
|
|
58
|
+
# enough.
|
|
58
59
|
# @param distribution [Symbol] the strategy to use for virtual partitioning. Can be
|
|
59
60
|
# either `:consistent` or `:balanced`. The `:balanced` strategy ensures balanced
|
|
60
61
|
# distribution of work across available workers while maintaining message order
|
|
@@ -33,17 +33,13 @@ module Karafka
|
|
|
33
33
|
module Routing
|
|
34
34
|
module Features
|
|
35
35
|
class Pausing < Base
|
|
36
|
-
# Config for pausing feature
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
) do
|
|
44
|
-
alias_method :active?, :active
|
|
45
|
-
alias_method :with_exponential_backoff?, :with_exponential_backoff
|
|
46
|
-
end
|
|
36
|
+
# Config for pausing feature.
|
|
37
|
+
#
|
|
38
|
+
# By convention each routing feature exposes a `Config`. The pause value object is defined
|
|
39
|
+
# in OSS (`Karafka::Routing::Features::Pausing::Config`) because the per-topic `#pause`
|
|
40
|
+
# reader defaults to the global config there, so the feature points its `Config` at that
|
|
41
|
+
# shared class rather than redefining it.
|
|
42
|
+
Config = Karafka::Routing::Features::Pausing::Config
|
|
47
43
|
end
|
|
48
44
|
end
|
|
49
45
|
end
|
|
@@ -42,10 +42,8 @@ module Karafka
|
|
|
42
42
|
File.join(Karafka.gem_root, "config", "locales", "pro_errors.yml")
|
|
43
43
|
).fetch("en").fetch("validations").fetch("routing").fetch("topic")
|
|
44
44
|
|
|
45
|
-
# Validate the nested
|
|
46
|
-
|
|
47
|
-
# so we only need to validate this one format
|
|
48
|
-
nested :pausing do
|
|
45
|
+
# Validate the nested pause configuration
|
|
46
|
+
nested :pause do
|
|
49
47
|
required(:active) { |val| [true, false].include?(val) }
|
|
50
48
|
required(:timeout) { |val| val.is_a?(Integer) && val.positive? }
|
|
51
49
|
required(:max_timeout) { |val| val.is_a?(Integer) && val.positive? }
|
|
@@ -56,13 +54,13 @@ module Karafka
|
|
|
56
54
|
virtual do |data, errors|
|
|
57
55
|
next unless errors.empty?
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
timeout =
|
|
61
|
-
max_timeout =
|
|
57
|
+
pause = data.fetch(:pause)
|
|
58
|
+
timeout = pause.fetch(:timeout)
|
|
59
|
+
max_timeout = pause.fetch(:max_timeout)
|
|
62
60
|
|
|
63
61
|
next if timeout <= max_timeout
|
|
64
62
|
|
|
65
|
-
[[%i[
|
|
63
|
+
[[%i[pause timeout], :max_timeout_vs_pause_max_timeout]]
|
|
66
64
|
end
|
|
67
65
|
end
|
|
68
66
|
end
|
|
@@ -35,84 +35,39 @@ module Karafka
|
|
|
35
35
|
class Pausing < Base
|
|
36
36
|
# Expansion allowing for a per topic pause strategy definitions
|
|
37
37
|
module Topic
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
super
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# Allows for per-topic pausing strategy setting
|
|
38
|
+
# Allows for per-topic pausing strategy setting.
|
|
39
|
+
#
|
|
40
|
+
# Overrides the OSS `#pause` reader (this module is prepended onto `Routing::Topic`).
|
|
41
|
+
# With no arguments it returns the current configuration, defaulting to the global
|
|
42
|
+
# `config.pause.*` settings via `super`. With arguments it overrides the pausing
|
|
43
|
+
# strategy for this topic and marks it as active.
|
|
48
44
|
#
|
|
49
45
|
# @param timeout [Integer] how long should we wait upon processing error (milliseconds)
|
|
50
46
|
# @param max_timeout [Integer] what is the max timeout in case of an exponential
|
|
51
47
|
# backoff (milliseconds)
|
|
52
48
|
# @param with_exponential_backoff [Boolean] should we use exponential backoff
|
|
53
|
-
# @return [Config] pausing config object
|
|
49
|
+
# @return [Karafka::Routing::Features::Pausing::Config] pausing config object
|
|
54
50
|
def pause(timeout: nil, max_timeout: nil, with_exponential_backoff: nil)
|
|
55
|
-
|
|
56
|
-
return pausing if timeout.nil? && max_timeout.nil? && with_exponential_backoff.nil?
|
|
51
|
+
config = super()
|
|
57
52
|
|
|
58
|
-
#
|
|
59
|
-
|
|
60
|
-
# will get the correct values
|
|
61
|
-
@pause_timeout = timeout if timeout
|
|
62
|
-
@pause_max_timeout = max_timeout if max_timeout
|
|
63
|
-
|
|
64
|
-
unless with_exponential_backoff.nil?
|
|
65
|
-
@pause_with_exponential_backoff = with_exponential_backoff
|
|
66
|
-
end
|
|
53
|
+
# If no arguments provided, just return the current (default or overridden) config
|
|
54
|
+
return config if timeout.nil? && max_timeout.nil? && with_exponential_backoff.nil?
|
|
67
55
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
active: false,
|
|
71
|
-
timeout: @pause_timeout || Karafka::App.config.pause.timeout,
|
|
72
|
-
max_timeout: @pause_max_timeout || Karafka::App.config.pause.max_timeout,
|
|
73
|
-
with_exponential_backoff: if @pause_with_exponential_backoff.nil?
|
|
74
|
-
Karafka::App.config.pause.with_exponential_backoff
|
|
75
|
-
else
|
|
76
|
-
@pause_with_exponential_backoff
|
|
77
|
-
end
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
@pausing.timeout = timeout if timeout
|
|
81
|
-
@pausing.max_timeout = max_timeout if max_timeout
|
|
56
|
+
config.timeout = timeout if timeout
|
|
57
|
+
config.max_timeout = max_timeout if max_timeout
|
|
82
58
|
|
|
83
59
|
unless with_exponential_backoff.nil?
|
|
84
|
-
|
|
60
|
+
config.with_exponential_backoff = with_exponential_backoff
|
|
85
61
|
end
|
|
86
62
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@pausing
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @return [Config] pausing configuration object
|
|
93
|
-
def pausing
|
|
94
|
-
@pausing ||= Config.new(
|
|
95
|
-
active: false,
|
|
96
|
-
timeout: @pause_timeout || Karafka::App.config.pause.timeout,
|
|
97
|
-
max_timeout: @pause_max_timeout || Karafka::App.config.pause.max_timeout,
|
|
98
|
-
with_exponential_backoff: if @pause_with_exponential_backoff.nil?
|
|
99
|
-
Karafka::App.config.pause.with_exponential_backoff
|
|
100
|
-
else
|
|
101
|
-
@pause_with_exponential_backoff
|
|
102
|
-
end
|
|
103
|
-
)
|
|
104
|
-
end
|
|
63
|
+
config.active = true
|
|
105
64
|
|
|
106
|
-
|
|
107
|
-
def pausing?
|
|
108
|
-
pausing.active?
|
|
65
|
+
config
|
|
109
66
|
end
|
|
110
67
|
|
|
111
|
-
# @return [
|
|
112
|
-
def
|
|
113
|
-
|
|
114
|
-
pausing: pausing.to_h
|
|
115
|
-
).freeze
|
|
68
|
+
# @return [Boolean] is pausing explicitly configured on a per-topic basis
|
|
69
|
+
def pause?
|
|
70
|
+
pause.active?
|
|
116
71
|
end
|
|
117
72
|
end
|
|
118
73
|
end
|
|
@@ -72,7 +72,13 @@ module Karafka
|
|
|
72
72
|
|
|
73
73
|
@states_reporter.call
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
# Clamp to the wall clock: a future-dated message timestamp (producer clock skew or an
|
|
76
|
+
# explicitly set future timestamp) must not be treated as proof of catch-up. Otherwise a
|
|
77
|
+
# single future-dated message read mid-backlog would flip `loaded!` while older tombstones
|
|
78
|
+
# at higher offsets are still unread, dispatching schedules whose cancelling tombstones
|
|
79
|
+
# have not been loaded yet (double dispatch). Mirrors the `[timestamp, now].min` clamp in
|
|
80
|
+
# the batch metadata builder.
|
|
81
|
+
recent_timestamp = [messages.last.timestamp.to_i, Time.now.to_i].min
|
|
76
82
|
post_started_timestamp = @tracker.started_at + GRACE_PERIOD
|
|
77
83
|
|
|
78
84
|
# If we started getting messages that are beyond the current time, it means we have
|
|
@@ -43,7 +43,12 @@ module Karafka
|
|
|
43
43
|
def call(message)
|
|
44
44
|
message_version = message.headers["schedule_schema_version"]
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
# Versions are semver, so they need to be compared segment-wise and not as strings
|
|
47
|
+
# ("1.2.0" is older than "1.10.0" but lexicographically greater)
|
|
48
|
+
message_gem_version = Gem::Version.new(message_version)
|
|
49
|
+
current_gem_version = Gem::Version.new(ScheduledMessages::SCHEMA_VERSION)
|
|
50
|
+
|
|
51
|
+
return if message_gem_version <= current_gem_version
|
|
47
52
|
|
|
48
53
|
raise Errors::IncompatibleSchemaError, message_version
|
|
49
54
|
end
|