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
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Processing
|
|
5
|
-
# Consumer-group-specific processing components (driven by rebalance callbacks and partition
|
|
6
|
-
# ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
|
|
7
5
|
module ConsumerGroups
|
|
8
6
|
module Strategies
|
|
9
7
|
# When using dead letter queue, processing won't stop after defined number of retries
|
|
@@ -64,6 +62,11 @@ module Karafka
|
|
|
64
62
|
return if coordinator.manual_pause?
|
|
65
63
|
|
|
66
64
|
mark_as_consumed(messages.last)
|
|
65
|
+
# Process-critical errors are never dispatched to the DLQ regardless of the retries
|
|
66
|
+
# state: the retry pause protects the partition during the critical shutdown and
|
|
67
|
+
# the failed batch is redelivered after the restart
|
|
68
|
+
elsif critical_error?(coordinator.consumption(self).cause)
|
|
69
|
+
retry_after_pause
|
|
67
70
|
elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
|
|
68
71
|
retry_after_pause
|
|
69
72
|
# If we've reached number of retries that we could, we need to skip the first message
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Processing
|
|
5
|
-
# Consumer-group-specific processing components (driven by rebalance callbacks and partition
|
|
6
|
-
# ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
|
|
7
5
|
module ConsumerGroups
|
|
8
6
|
module Strategies
|
|
9
7
|
# Same as pure dead letter queue but we do not marked failed message as consumed
|
|
@@ -23,6 +21,11 @@ module Karafka
|
|
|
23
21
|
|
|
24
22
|
if coordinator.success?
|
|
25
23
|
coordinator.pause_tracker.reset
|
|
24
|
+
# Process-critical errors are never dispatched to the DLQ regardless of the retries
|
|
25
|
+
# state: the retry pause protects the partition during the critical shutdown and
|
|
26
|
+
# the failed batch is redelivered after the restart
|
|
27
|
+
elsif critical_error?(coordinator.consumption(self).cause)
|
|
28
|
+
retry_after_pause
|
|
26
29
|
elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
|
|
27
30
|
retry_after_pause
|
|
28
31
|
# If we've reached number of retries that we could, we need to skip the first message
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Processing
|
|
5
|
-
# Consumer-group-specific processing components (driven by rebalance callbacks and partition
|
|
6
|
-
# ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
|
|
7
5
|
module ConsumerGroups
|
|
8
6
|
module Strategies
|
|
9
|
-
# When using manual offset management, we do not mark as consumed after successful
|
|
7
|
+
# When using manual offset management, we do not mark as consumed after successful
|
|
8
|
+
# processing
|
|
10
9
|
module Mom
|
|
11
10
|
include Default
|
|
12
11
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Processing
|
|
5
|
-
# Consumer-group-specific processing components (driven by rebalance callbacks and partition
|
|
6
|
-
# ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
|
|
7
5
|
module ConsumerGroups
|
|
8
6
|
# Selector of appropriate processing strategy matching topic combinations
|
|
9
7
|
class StrategySelector
|
|
@@ -45,10 +45,16 @@ module Karafka
|
|
|
45
45
|
|
|
46
46
|
# Fetches a single job, processes it and marks as completed.
|
|
47
47
|
#
|
|
48
|
-
# @note
|
|
49
|
-
#
|
|
48
|
+
# @note No user or framework errors should propagate this far. If they do, it is a critical
|
|
49
|
+
# error that we instrument while keeping the worker alive.
|
|
50
50
|
#
|
|
51
51
|
# @note Upon closing the jobs queue, worker will close it's thread
|
|
52
|
+
#
|
|
53
|
+
# @return [Boolean] should the worker keep running. False only when the jobs queue is
|
|
54
|
+
# closed (full shutdown) or a downscale sentinel was received. This decision is
|
|
55
|
+
# deliberately decoupled from the processing flow result: the flow passes through the
|
|
56
|
+
# user-redefinable `#wrap`, whose return value (or an error raised in user code or in an
|
|
57
|
+
# instrumentation subscriber) must never be able to silently kill the worker thread.
|
|
52
58
|
def process
|
|
53
59
|
job = @jobs_queue.pop
|
|
54
60
|
|
|
@@ -76,10 +82,10 @@ module Karafka
|
|
|
76
82
|
end
|
|
77
83
|
|
|
78
84
|
job.after_call
|
|
79
|
-
|
|
80
|
-
true
|
|
81
85
|
end
|
|
82
86
|
end
|
|
87
|
+
|
|
88
|
+
true
|
|
83
89
|
else
|
|
84
90
|
# nil means either queue closed (full shutdown) or pool downscaling.
|
|
85
91
|
# Either way, deregister from pool so it reflects the actual worker count.
|
|
@@ -87,9 +93,7 @@ module Karafka
|
|
|
87
93
|
false
|
|
88
94
|
end
|
|
89
95
|
# We signal critical exceptions, notify and do not allow worker to fail
|
|
90
|
-
# rubocop:disable Lint/RescueException
|
|
91
96
|
rescue Exception => e
|
|
92
|
-
# rubocop:enable Lint/RescueException
|
|
93
97
|
monitor.instrument(
|
|
94
98
|
"error.occurred",
|
|
95
99
|
caller: self,
|
|
@@ -98,6 +102,10 @@ module Karafka
|
|
|
98
102
|
error: e,
|
|
99
103
|
type: "worker.process.error"
|
|
100
104
|
)
|
|
105
|
+
|
|
106
|
+
# Keep the worker alive. Without an explicit true this arm would return the result of
|
|
107
|
+
# the instrumentation call (nil) and the worker thread would silently exit
|
|
108
|
+
true
|
|
101
109
|
ensure
|
|
102
110
|
# job can be nil when the queue is being closed or during pool downscaling
|
|
103
111
|
if job
|
|
@@ -39,6 +39,13 @@ module Karafka
|
|
|
39
39
|
# after a worker exits, so thread names remain unique across the lifetime of the process
|
|
40
40
|
# and make it easy to correlate log entries with specific worker generations.
|
|
41
41
|
@next_index = 0
|
|
42
|
+
# Number of downscale sentinels enqueued but not yet picked up by a worker. Workers
|
|
43
|
+
# deregister asynchronously, so the live thread count alone overstates the pool between
|
|
44
|
+
# a scale-down request and its completion. All sizing decisions use the committed size
|
|
45
|
+
# (live workers minus pending shrinks) so repeated or overlapping scale-down requests do
|
|
46
|
+
# not enqueue duplicate sentinels and drain the pool below the requested target (or
|
|
47
|
+
# below the minimum of one worker).
|
|
48
|
+
@pending_shrinks = 0
|
|
42
49
|
end
|
|
43
50
|
|
|
44
51
|
# Scale pool towards `target` workers (minimum 1).
|
|
@@ -63,7 +70,9 @@ module Karafka
|
|
|
63
70
|
event = nil
|
|
64
71
|
|
|
65
72
|
@mutex.synchronize do
|
|
66
|
-
|
|
73
|
+
# Compute against the committed size, not the live thread count: sentinels already in
|
|
74
|
+
# flight are removals this pool is committed to, just not yet executed by the workers
|
|
75
|
+
current = @workers.size - @pending_shrinks
|
|
67
76
|
delta = target - current
|
|
68
77
|
|
|
69
78
|
if delta.positive?
|
|
@@ -106,6 +115,11 @@ module Karafka
|
|
|
106
115
|
@mutex.synchronize do
|
|
107
116
|
@workers.delete(worker)
|
|
108
117
|
@size = @workers.size
|
|
118
|
+
# A worker exits either because it picked up a downscale sentinel or because the jobs
|
|
119
|
+
# queue was closed for shutdown. The worker cannot tell those apart, so pending
|
|
120
|
+
# removals are settled here, with a floor because shutdown exits may have no pending
|
|
121
|
+
# shrink to consume
|
|
122
|
+
@pending_shrinks -= 1 if @pending_shrinks.positive?
|
|
109
123
|
end
|
|
110
124
|
end
|
|
111
125
|
|
|
@@ -142,14 +156,17 @@ module Karafka
|
|
|
142
156
|
#
|
|
143
157
|
# @param count [Integer] number of workers to remove
|
|
144
158
|
# @return [Array, nil] instrumentation event args or nil if no-op
|
|
145
|
-
# @note Never shrinks below 1 worker
|
|
159
|
+
# @note Never shrinks below 1 worker, including removals already in flight - the cap is
|
|
160
|
+
# computed against the committed size, not the live thread count.
|
|
146
161
|
def shrink(count)
|
|
147
|
-
|
|
162
|
+
committed = @workers.size - @pending_shrinks
|
|
163
|
+
effective = [count, committed - 1].min
|
|
148
164
|
return if effective <= 0
|
|
149
165
|
|
|
150
166
|
from = @workers.size
|
|
167
|
+
@pending_shrinks += effective
|
|
151
168
|
effective.times { @jobs_queue << nil }
|
|
152
|
-
to =
|
|
169
|
+
to = committed - effective
|
|
153
170
|
|
|
154
171
|
["worker.scaling.down", { workers_pool: self, from: from, to: to }]
|
|
155
172
|
end
|
data/lib/karafka/railtie.rb
CHANGED
|
@@ -12,8 +12,8 @@ module Karafka
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Ensures, that when declarative topics strict requirement is on, all topics have
|
|
15
|
-
# declarative definition (including DLQ topics)
|
|
16
|
-
#
|
|
15
|
+
# declarative definition (including DLQ topics). It will ignore routing pattern topics
|
|
16
|
+
# because those topics are virtual
|
|
17
17
|
virtual do |data, errors|
|
|
18
18
|
next unless errors.empty?
|
|
19
19
|
# Do not validate declaratives unless required and explicitly enabled
|
|
@@ -7,11 +7,12 @@ module Karafka
|
|
|
7
7
|
class ActiveJob < Base
|
|
8
8
|
# Topic extensions to be able to check if given topic is ActiveJob topic
|
|
9
9
|
#
|
|
10
|
-
# @note ActiveJob topics do not have per-topic deserializer configuration. The
|
|
11
|
-
# is configured globally via `config.internal.active_job.deserializer`
|
|
12
|
-
# serializes jobs before dispatching them, requiring a consistent
|
|
13
|
-
# across all ActiveJob topics. If you need custom serialization
|
|
14
|
-
# configure it once at the application level rather than
|
|
10
|
+
# @note ActiveJob topics do not have per-topic deserializer configuration. The
|
|
11
|
+
# deserializer is configured globally via `config.internal.active_job.deserializer`
|
|
12
|
+
# because Rails serializes jobs before dispatching them, requiring a consistent
|
|
13
|
+
# serialization format across all ActiveJob topics. If you need custom serialization
|
|
14
|
+
# (e.g., Avro, Protobuf), configure it once at the application level rather than
|
|
15
|
+
# per-topic.
|
|
15
16
|
module Topic
|
|
16
17
|
# This method sets up the extra instance variable to nil before calling
|
|
17
18
|
# the parent class initializer. The explicit initialization
|
|
@@ -16,8 +16,8 @@ module Karafka
|
|
|
16
16
|
super
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
# @param active [Boolean] should we stop managing the offset in Karafka and make the
|
|
20
|
-
# responsible for marking messages as consumed.
|
|
19
|
+
# @param active [Boolean] should we stop managing the offset in Karafka and make the
|
|
20
|
+
# user responsible for marking messages as consumed.
|
|
21
21
|
# @return [Config] defined config
|
|
22
22
|
#
|
|
23
23
|
# @note Since this feature supports only one setting (active), we can use the old API
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module Pausing
|
|
7
|
+
# Per-topic pause (backoff) configuration value object.
|
|
8
|
+
#
|
|
9
|
+
# Defaults to the global `config.pause.*` settings unless overridden on a per-topic basis.
|
|
10
|
+
#
|
|
11
|
+
# Unlike most feature configs, `active` here does not switch the behavior on or off - the
|
|
12
|
+
# pause/backoff always applies. It only marks whether these settings were explicitly set
|
|
13
|
+
# for this topic (`true`) or inherited from the global defaults (`false`).
|
|
14
|
+
Config = Struct.new(
|
|
15
|
+
:active,
|
|
16
|
+
:timeout,
|
|
17
|
+
:max_timeout,
|
|
18
|
+
:with_exponential_backoff,
|
|
19
|
+
keyword_init: true
|
|
20
|
+
) do
|
|
21
|
+
alias_method :active?, :active
|
|
22
|
+
alias_method :with_exponential_backoff?, :with_exponential_backoff
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
# Namespace holding the pause (backoff) routing configuration. There is no OSS pausing
|
|
7
|
+
# feature to activate here - the backoff behavior is part of the topic itself and its
|
|
8
|
+
# settings default to the global `config.pause.*`.
|
|
9
|
+
module Pausing
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -16,7 +16,7 @@ module Karafka
|
|
|
16
16
|
|
|
17
17
|
attr_reader :id, :name, :topics, :kafka, :group, :position
|
|
18
18
|
|
|
19
|
-
# Backwards compatible alias for `#group`. Kept purely for compatibility
|
|
19
|
+
# Backwards compatible alias for `#group`. Kept purely for compatibility - this is an
|
|
20
20
|
# unconditional alias and performs no type validation, so callers should prefer `#group`
|
|
21
21
|
# once additional group types (e.g. KIP-932 share groups) land.
|
|
22
22
|
alias_method :consumer_group, :group
|
|
@@ -14,7 +14,7 @@ module Karafka
|
|
|
14
14
|
attr_reader :id, :name, :group
|
|
15
15
|
attr_writer :consumer
|
|
16
16
|
|
|
17
|
-
# Backwards compatible alias for `#group`. Kept purely for compatibility
|
|
17
|
+
# Backwards compatible alias for `#group`. Kept purely for compatibility - this is an
|
|
18
18
|
# unconditional alias and performs no type validation, so callers should prefer `#group`
|
|
19
19
|
# once additional group types (e.g. KIP-932 share groups) land.
|
|
20
20
|
alias_method :consumer_group, :group
|
|
@@ -32,9 +32,6 @@ module Karafka
|
|
|
32
32
|
max_wait_time
|
|
33
33
|
initial_offset
|
|
34
34
|
consumer_persistence
|
|
35
|
-
pause_timeout
|
|
36
|
-
pause_max_timeout
|
|
37
|
-
pause_with_exponential_backoff
|
|
38
35
|
].freeze
|
|
39
36
|
|
|
40
37
|
private_constant :INHERITABLE_ATTRIBUTES
|
|
@@ -47,9 +44,9 @@ module Karafka
|
|
|
47
44
|
@group = group
|
|
48
45
|
@attributes = {}
|
|
49
46
|
@active = true
|
|
50
|
-
#
|
|
51
|
-
#
|
|
52
|
-
#
|
|
47
|
+
# We use identifier related to the group that owns a topic, because from Karafka 0.6 we can
|
|
48
|
+
# handle multiple Kafka instances with the same process and we can have same topic name
|
|
49
|
+
# across multiple groups
|
|
53
50
|
@id = "#{group.id}_#{@name}"
|
|
54
51
|
@consumer = nil
|
|
55
52
|
@active_assigned = false
|
|
@@ -58,6 +55,10 @@ module Karafka
|
|
|
58
55
|
INHERITABLE_ATTRIBUTES.each do |attribute|
|
|
59
56
|
instance_variable_set("@#{attribute}", nil)
|
|
60
57
|
end
|
|
58
|
+
|
|
59
|
+
# Explicit nil initialization for Ruby's object shapes optimization. The per-topic pause
|
|
60
|
+
# config is built lazily on first read, defaulting to the global `config.pause.*` settings.
|
|
61
|
+
@pause = nil
|
|
61
62
|
end
|
|
62
63
|
|
|
63
64
|
INHERITABLE_ATTRIBUTES.each do |attribute|
|
|
@@ -73,6 +74,17 @@ module Karafka
|
|
|
73
74
|
RUBY
|
|
74
75
|
end
|
|
75
76
|
|
|
77
|
+
# @return [Karafka::Routing::Features::Pausing::Config] per-topic pause configuration,
|
|
78
|
+
# reflecting the root `config.pause.*` settings.
|
|
79
|
+
def pause
|
|
80
|
+
@pause ||= Features::Pausing::Config.new(
|
|
81
|
+
active: false,
|
|
82
|
+
timeout: Karafka::App.config.pause.timeout,
|
|
83
|
+
max_timeout: Karafka::App.config.pause.max_timeout,
|
|
84
|
+
with_exponential_backoff: Karafka::App.config.pause.with_exponential_backoff
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
76
88
|
# Often users want to have the same basic cluster setup with small setting alterations
|
|
77
89
|
# This method allows us to do so by setting `inherit` to `true`. Whe inherit is enabled,
|
|
78
90
|
# settings will be merged with defaults.
|
|
@@ -155,6 +167,7 @@ module Karafka
|
|
|
155
167
|
name: name,
|
|
156
168
|
active: active?,
|
|
157
169
|
consumer: consumer,
|
|
170
|
+
pause: pause.to_h,
|
|
158
171
|
group_id: group.id,
|
|
159
172
|
# Kept as a reference alongside `group_id` for backwards compatibility. Will be removed
|
|
160
173
|
# in Karafka 3.0.
|
|
@@ -7,13 +7,33 @@ module Karafka
|
|
|
7
7
|
include Enumerable
|
|
8
8
|
extend Forwardable
|
|
9
9
|
|
|
10
|
-
def_delegators :@accumulator, :[], :size, :empty?, :last,
|
|
10
|
+
def_delegators :@accumulator, :[], :size, :empty?, :last, :map!, :sort_by!, :reverse!
|
|
11
11
|
|
|
12
12
|
# @param topics_array [Array<Karafka::Routing::Topic>] array with topics
|
|
13
13
|
def initialize(topics_array)
|
|
14
14
|
@accumulator = topics_array.dup
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
# Adds a topic using copy-on-write: we publish a brand-new accumulator array instead of
|
|
18
|
+
# mutating the existing one in place.
|
|
19
|
+
#
|
|
20
|
+
# @param topic [Karafka::Routing::Topic] topic that should become part of this consumer
|
|
21
|
+
# group's topics
|
|
22
|
+
# @return [self]
|
|
23
|
+
#
|
|
24
|
+
# @note Topics can be appended to this collection at runtime from one thread while other
|
|
25
|
+
# threads iterate the same collection (for example during routing lookups). Swapping the
|
|
26
|
+
# `@accumulator` reference atomically (rather than appending in place) guarantees a
|
|
27
|
+
# concurrent `#each` always traverses a complete, immutable snapshot: it either sees the
|
|
28
|
+
# newly added topic or it does not, but never a torn array. This holds on every Ruby
|
|
29
|
+
# runtime, not only on MRI's GIL. The in-place mutators above (`map!`, `sort_by!`,
|
|
30
|
+
# `reverse!`) only run while routes are built at boot, single-threaded, so they do not
|
|
31
|
+
# need the same treatment.
|
|
32
|
+
def <<(topic)
|
|
33
|
+
@accumulator += [topic]
|
|
34
|
+
self
|
|
35
|
+
end
|
|
36
|
+
|
|
17
37
|
# Yields each topic
|
|
18
38
|
def each(&)
|
|
19
39
|
@accumulator.each(&)
|
data/lib/karafka/server.rb
CHANGED
|
@@ -168,6 +168,15 @@ module Karafka
|
|
|
168
168
|
# otherwise we would overwrite the shutdown process of the process that started Karafka
|
|
169
169
|
return unless process.supervised?
|
|
170
170
|
|
|
171
|
+
# We intentionally do NOT flush or close the producer before the `Kernel.exit!` below.
|
|
172
|
+
# Forceful shutdown is a last resort - a job already exceeded `shutdown_timeout` - and it
|
|
173
|
+
# is expected that in-flight, async-buffered data (user `produce_async` calls and DLQ
|
|
174
|
+
# `produce_async` copies) may be lost. Flushing here would be risky precisely when it
|
|
175
|
+
# matters: the producer (or its connection pool) may itself be the resource that is blocked
|
|
176
|
+
# (e.g. an unreachable broker), so waiting on it could stall or hang the very forceful exit
|
|
177
|
+
# that must guarantee the process terminates. On a normal (graceful) shutdown the producer
|
|
178
|
+
# is still closed via the `ensure` block below, which `exit!` deliberately skips here.
|
|
179
|
+
#
|
|
171
180
|
# exit! is not within the instrumentation as it would not trigger due to exit
|
|
172
181
|
Kernel.exit!(forceful_exit_code)
|
|
173
182
|
ensure
|
data/lib/karafka/setup/config.rb
CHANGED
|
@@ -22,8 +22,8 @@ module Karafka
|
|
|
22
22
|
# option token [String, false] - license token issued when you acquire a Pro license
|
|
23
23
|
# Leave false if using the LGPL version and all is going to work just fine :)
|
|
24
24
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
25
|
+
# By using the commercial components, you accept the LICENSE-COMM commercial license terms
|
|
26
|
+
# and conditions
|
|
27
27
|
setting :token, default: false
|
|
28
28
|
# option entity [String] for whom we did issue the license
|
|
29
29
|
setting :entity, default: ""
|
|
@@ -88,8 +88,8 @@ module Karafka
|
|
|
88
88
|
setting :token_provider_listener, default: false
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
# rdkafka default options
|
|
92
|
-
#
|
|
91
|
+
# rdkafka default options See
|
|
92
|
+
# https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
|
|
93
93
|
setting :kafka, default: {}
|
|
94
94
|
|
|
95
95
|
# Public configuration for swarm operations
|
|
@@ -163,9 +163,8 @@ module Karafka
|
|
|
163
163
|
setting :internal do
|
|
164
164
|
# option status [Karafka::Status] app status
|
|
165
165
|
setting :status, default: Status.new
|
|
166
|
-
# option process [Karafka::Process] process status
|
|
167
|
-
#
|
|
168
|
-
# instances
|
|
166
|
+
# option process [Karafka::Process] process status. In the future, we need to have a single
|
|
167
|
+
# process representation for all the karafka instances
|
|
169
168
|
setting :process, default: Process.new
|
|
170
169
|
# Interval of "ticking". This is used to define the maximum time between consecutive
|
|
171
170
|
# polling of the main rdkafka queue. It should match also the `statistics.interval.ms`
|
|
@@ -314,6 +313,17 @@ module Karafka
|
|
|
314
313
|
# option worker_job_call_wrapper [Proc, false] callable object that will be used to wrap
|
|
315
314
|
# the worker execution of a job or false if no wrapper needed
|
|
316
315
|
setting :worker_job_call_wrapper, default: false
|
|
316
|
+
# option critical_errors [Array<Class>] errors that indicate that the process integrity
|
|
317
|
+
# is compromised or that termination was explicitly requested. They are not retried
|
|
318
|
+
# in-process when raised from the consumption flow: SystemExit means someone called
|
|
319
|
+
# `exit` and retrying would invert that intent (and loop forever on a deterministic
|
|
320
|
+
# raise), while NoMemoryError means the VM cannot be trusted to execute a retry.
|
|
321
|
+
# Their failure is still recorded (so nothing gets marked, they are never dispatched
|
|
322
|
+
# to a DLQ and the retry pause protects the partition) and a graceful shutdown is
|
|
323
|
+
# initiated instead - redelivery after restart preserves the processing guarantees
|
|
324
|
+
# through the process death. Can be extended with user-specific fatal error classes
|
|
325
|
+
# that should terminate the process rather than be retried.
|
|
326
|
+
setting :critical_errors, default: [SystemExit, SignalException, NoMemoryError].freeze
|
|
317
327
|
|
|
318
328
|
# Consumer-group-specific processing defaults. When share groups land, a parallel
|
|
319
329
|
# `share_groups` namespace will hold their equivalents.
|
|
@@ -343,6 +353,36 @@ module Karafka
|
|
|
343
353
|
setting :parser, default: Messages::Parser.new
|
|
344
354
|
end
|
|
345
355
|
|
|
356
|
+
# Things related to librdkafka statistics decoration prior to their emission
|
|
357
|
+
setting :statistics do
|
|
358
|
+
# Consumer groups related statistics settings
|
|
359
|
+
setting :consumer_groups do
|
|
360
|
+
# option decorator_class [Class] class used to decorate raw librdkafka statistics
|
|
361
|
+
# (adds delta/freeze-duration values) before `statistics.emitted` is instrumented.
|
|
362
|
+
# Exposed so it can be replaced with a custom decorator (e.g. one that also
|
|
363
|
+
# enriches or corrects specific values) without touching the callback that uses
|
|
364
|
+
# it.
|
|
365
|
+
setting :decorator_class, default: Instrumentation::Callbacks::ConsumerGroups::Decorator
|
|
366
|
+
|
|
367
|
+
# Active refreshing of watermarks and lags for long-paused partitions (Pro).
|
|
368
|
+
# librdkafka only updates watermark offsets and lags from fetch responses, so
|
|
369
|
+
# partitions paused for a long time report frozen values in statistics. When
|
|
370
|
+
# enabled, they are refreshed via the running consumer connection and overlaid onto
|
|
371
|
+
# the emitted statistics.
|
|
372
|
+
setting :lag_compensation do
|
|
373
|
+
# option interval [Integer] how often (ms) at most to refresh watermarks and lags
|
|
374
|
+
# of long-paused partitions. 0 disables the feature entirely.
|
|
375
|
+
setting :interval, default: 0
|
|
376
|
+
|
|
377
|
+
# option pause_age [Integer] how long (ms) a partition needs to stay paused to
|
|
378
|
+
# qualify for the compensation. Short pause/resume cycles reset the clock and
|
|
379
|
+
# never qualify. Minimum accepted value is 5 seconds as statistics of partitions
|
|
380
|
+
# paused shorter are fresh enough to make compensating them pointless.
|
|
381
|
+
setting :pause_age, default: 30_000
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
346
386
|
# Karafka components for ActiveJob
|
|
347
387
|
setting :active_job do
|
|
348
388
|
# option dispatcher [Karafka::ActiveJob::Dispatcher] default dispatcher for ActiveJob
|
|
@@ -365,54 +405,6 @@ module Karafka
|
|
|
365
405
|
# Thanks to that we have an initial state out of the box.
|
|
366
406
|
configure
|
|
367
407
|
|
|
368
|
-
# Backwards compatibility: Add old flat API methods to the config instance
|
|
369
|
-
# These delegate to the new nested pause config
|
|
370
|
-
# @deprecated Will be removed in Karafka 2.6
|
|
371
|
-
#
|
|
372
|
-
# Prior to the introduction of nested pause configuration, pause-related settings were
|
|
373
|
-
# accessed directly on the config object (e.g., `config.pause_timeout`). With the nested
|
|
374
|
-
# structure introduced, these settings moved to `config.pause.timeout`, etc.
|
|
375
|
-
#
|
|
376
|
-
# This instance_eval block adds delegation methods to maintain backwards compatibility,
|
|
377
|
-
# allowing existing code using the old flat API to continue working without modification.
|
|
378
|
-
config.instance_eval do
|
|
379
|
-
# @return [Integer] delegated timeout value from pause.timeout
|
|
380
|
-
# @deprecated Use config.pause.timeout instead
|
|
381
|
-
def pause_timeout
|
|
382
|
-
pause.timeout
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
# @param value [Integer] timeout value to set
|
|
386
|
-
# @deprecated Use config.pause.timeout= instead
|
|
387
|
-
def pause_timeout=(value)
|
|
388
|
-
pause.timeout = value
|
|
389
|
-
end
|
|
390
|
-
|
|
391
|
-
# @return [Integer] delegated max_timeout value from pause.max_timeout
|
|
392
|
-
# @deprecated Use config.pause.max_timeout instead
|
|
393
|
-
def pause_max_timeout
|
|
394
|
-
pause.max_timeout
|
|
395
|
-
end
|
|
396
|
-
|
|
397
|
-
# @param value [Integer] max timeout value to set
|
|
398
|
-
# @deprecated Use config.pause.max_timeout= instead
|
|
399
|
-
def pause_max_timeout=(value)
|
|
400
|
-
pause.max_timeout = value
|
|
401
|
-
end
|
|
402
|
-
|
|
403
|
-
# @return [Boolean] delegated exponential backoff flag from pause.with_exponential_backoff
|
|
404
|
-
# @deprecated Use config.pause.with_exponential_backoff instead
|
|
405
|
-
def pause_with_exponential_backoff
|
|
406
|
-
pause.with_exponential_backoff
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
# @param value [Boolean] exponential backoff flag to set
|
|
410
|
-
# @deprecated Use config.pause.with_exponential_backoff= instead
|
|
411
|
-
def pause_with_exponential_backoff=(value)
|
|
412
|
-
pause.with_exponential_backoff = value
|
|
413
|
-
end
|
|
414
|
-
end
|
|
415
|
-
|
|
416
408
|
class << self
|
|
417
409
|
# Configuring method
|
|
418
410
|
def setup(&)
|
|
@@ -451,6 +443,11 @@ module Karafka
|
|
|
451
443
|
# Post-setup configure all routing features that would need this
|
|
452
444
|
Routing::Features::Base.post_setup_all(config)
|
|
453
445
|
|
|
446
|
+
# Subscribe the critical errors listener so process-critical errors reported anywhere
|
|
447
|
+
# in the framework escalate to a graceful shutdown. Subscribed before any other
|
|
448
|
+
# internal listener (including the Pro post-setup subscriptions) so it reacts first
|
|
449
|
+
config.monitor.subscribe(Instrumentation::CriticalErrorsListener.instance)
|
|
450
|
+
|
|
454
451
|
# Runs things that need to be executed after config is defined and all the components
|
|
455
452
|
# are also configured
|
|
456
453
|
Pro::Loader.post_setup_all(config) if Karafka.pro?
|
|
@@ -197,7 +197,8 @@ module Karafka
|
|
|
197
197
|
# end
|
|
198
198
|
#
|
|
199
199
|
# @example Direct producer assignment
|
|
200
|
-
# custom_producer = WaterDrop::Producer.new { |c|
|
|
200
|
+
# custom_producer = WaterDrop::Producer.new { |c|
|
|
201
|
+
# c.kafka = { 'bootstrap.servers' => 'localhost:9092' } }
|
|
201
202
|
# config.producer = custom_producer
|
|
202
203
|
def producer(instance = READ, &block)
|
|
203
204
|
if block
|
|
@@ -124,6 +124,9 @@ module Karafka
|
|
|
124
124
|
required(:jobs_queue_class) { |val| !val.nil? }
|
|
125
125
|
required(:scheduler_class) { |val| !val.nil? }
|
|
126
126
|
required(:worker_job_call_wrapper) { |val| val == false || val.respond_to?(:wrap) }
|
|
127
|
+
required(:critical_errors) do |val|
|
|
128
|
+
val.is_a?(Array) && val.all? { |klass| klass.is_a?(Class) && klass <= Exception }
|
|
129
|
+
end
|
|
127
130
|
|
|
128
131
|
nested(:consumer_groups) do
|
|
129
132
|
required(:jobs_builder) { |val| !val.nil? }
|
|
@@ -136,6 +139,17 @@ module Karafka
|
|
|
136
139
|
end
|
|
137
140
|
end
|
|
138
141
|
|
|
142
|
+
nested(:statistics) do
|
|
143
|
+
nested(:consumer_groups) do
|
|
144
|
+
required(:decorator_class) { |val| !val.nil? }
|
|
145
|
+
|
|
146
|
+
nested(:lag_compensation) do
|
|
147
|
+
required(:interval) { |val| val.is_a?(Integer) && val >= 0 }
|
|
148
|
+
required(:pause_age) { |val| val.is_a?(Integer) && val >= 5_000 }
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
139
153
|
nested(:active_job) do
|
|
140
154
|
required(:dispatcher) { |val| !val.nil? }
|
|
141
155
|
required(:job_options_contract) { |val| !val.nil? }
|