karafka 2.5.9 → 2.6.0.beta1
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 +34 -0
- data/certs/expired.txt +83 -0
- data/config/locales/errors.yml +17 -7
- data/karafka.gemspec +3 -3
- data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -2
- data/lib/karafka/active_job/job_extensions.rb +1 -2
- data/lib/karafka/admin/configs/resource.rb +1 -2
- data/lib/karafka/admin/consumer_groups.rb +109 -98
- data/lib/karafka/admin/isolation_levels.rb +22 -0
- data/lib/karafka/admin/topics.rb +103 -8
- data/lib/karafka/admin.rb +59 -31
- data/lib/karafka/app.rb +16 -5
- data/lib/karafka/base_consumer.rb +2 -2
- data/lib/karafka/cli/contracts/server.rb +4 -4
- data/lib/karafka/cli/info.rb +1 -1
- data/lib/karafka/cli/topics/base.rb +10 -18
- data/lib/karafka/cli/topics/repartition.rb +1 -1
- data/lib/karafka/connection/client.rb +40 -9
- data/lib/karafka/connection/consumer_groups/rebalance_manager.rb +120 -0
- data/lib/karafka/connection/listener.rb +8 -7
- data/lib/karafka/connection/listeners_batch.rb +1 -1
- data/lib/karafka/connection/mode.rb +1 -2
- data/lib/karafka/connection/raw_messages_buffer.rb +0 -5
- data/lib/karafka/declaratives/builder.rb +65 -0
- data/lib/karafka/declaratives/contracts/topic.rb +28 -0
- data/lib/karafka/declaratives/repository.rb +52 -0
- data/lib/karafka/declaratives/topic.rb +100 -0
- data/lib/karafka/declaratives.rb +9 -0
- data/lib/karafka/helpers/interval_runner.rb +2 -2
- data/lib/karafka/instrumentation/assignments_tracker.rb +65 -2
- data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +56 -0
- data/lib/karafka/instrumentation/callbacks/consumer_groups/rebalance.rb +93 -0
- data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +59 -0
- data/lib/karafka/instrumentation/logger_listener.rb +27 -9
- data/lib/karafka/instrumentation/notifications.rb +2 -0
- data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +14 -17
- data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +8 -9
- data/lib/karafka/instrumentation/vendors/kubernetes/base_listener.rb +7 -3
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +13 -10
- data/lib/karafka/licenser.rb +16 -3
- data/lib/karafka/pro/active_job/consumer.rb +1 -2
- data/lib/karafka/pro/active_job/dispatcher.rb +1 -2
- data/lib/karafka/pro/admin/recovery.rb +19 -19
- data/lib/karafka/pro/base_consumer.rb +3 -3
- data/lib/karafka/pro/cli/contracts/server.rb +5 -5
- data/lib/karafka/pro/cli/parallel_segments/base.rb +7 -7
- data/lib/karafka/pro/cli/parallel_segments/collapse.rb +4 -4
- data/lib/karafka/pro/cli/parallel_segments/distribute.rb +6 -6
- data/lib/karafka/pro/iterator/tpl_builder.rb +38 -18
- data/lib/karafka/pro/loader.rb +15 -12
- data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +84 -0
- data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +97 -0
- data/lib/karafka/pro/processing/consumer_groups/collapser.rb +84 -0
- data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +202 -0
- data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +124 -0
- data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +157 -0
- data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +212 -0
- data/lib/karafka/pro/processing/{filters/expirer.rb → consumer_groups/executor.rb} +17 -31
- data/lib/karafka/pro/processing/{jobs/periodic.rb → consumer_groups/expansions_selector.rb} +18 -21
- data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +103 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +92 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +78 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +99 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +106 -0
- data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +79 -0
- data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/consume_non_blocking.rb +21 -17
- data/lib/karafka/pro/processing/{virtual_partitions/distributors/consistent.rb → consumer_groups/jobs/eofed_non_blocking.rb} +16 -14
- data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +64 -0
- data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/periodic_non_blocking.rb +16 -11
- data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/revoked_non_blocking.rb +19 -15
- data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +95 -0
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +66 -0
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +154 -0
- data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +68 -0
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +102 -0
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +115 -0
- data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +96 -0
- data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +98 -0
- data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +90 -0
- data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +154 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +93 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +99 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +92 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +90 -0
- data/lib/karafka/pro/processing/{strategies/aj/dlq_ftr_lrj_mom.rb → consumer_groups/strategies/aj/dlq_lrj_mom.rb} +37 -39
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +90 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +84 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +89 -0
- data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_lrj_mom.rb +20 -15
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +91 -0
- data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_mom.rb +20 -15
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +80 -0
- data/lib/karafka/pro/processing/{strategies/mom/default.rb → consumer_groups/strategies/aj/lrj_mom.rb} +18 -22
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +106 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +58 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +74 -0
- data/lib/karafka/pro/processing/{strategies/lrj/vp.rb → consumer_groups/strategies/base.rb} +9 -14
- data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +421 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +285 -0
- data/lib/karafka/pro/processing/{strategies/dlq/lrj.rb → consumer_groups/strategies/dlq/ftr.rb} +30 -29
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +95 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +97 -0
- data/lib/karafka/pro/processing/{executor.rb → consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb} +26 -15
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +63 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +97 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +63 -0
- data/lib/karafka/pro/{routing/features/patterns/patterns.rb → processing/consumer_groups/strategies/dlq/ftr_vp.rb} +22 -12
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +83 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +100 -0
- data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/dlq/lrj_mom_vp.rb +18 -13
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +61 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +96 -0
- data/lib/karafka/pro/processing/{strategies/lrj → consumer_groups/strategies/dlq}/mom_vp.rb +19 -15
- data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +62 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +146 -0
- data/lib/karafka/pro/processing/{strategies/mom/ftr.rb → consumer_groups/strategies/ftr/vp.rb} +20 -28
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +119 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +94 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +92 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +62 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +61 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +101 -0
- data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +60 -0
- data/lib/karafka/pro/processing/{strategies/mom → consumer_groups/strategies/lrj}/vp.rb +18 -12
- data/lib/karafka/pro/processing/{strategies/aj/mom_vp.rb → consumer_groups/strategies/mom/default.rb} +22 -23
- data/lib/karafka/pro/processing/{strategies/aj/ftr_mom_vp.rb → consumer_groups/strategies/mom/ftr.rb} +28 -28
- data/lib/karafka/pro/processing/{virtual_partitions/distributors/base.rb → consumer_groups/strategies/mom/ftr_vp.rb} +19 -14
- data/lib/karafka/pro/processing/{strategies/aj/mom.rb → consumer_groups/strategies/mom/vp.rb} +16 -12
- data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +197 -0
- data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +106 -0
- data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +73 -0
- data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +82 -0
- data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +59 -0
- data/lib/karafka/pro/processing/{strategies/dlq/ftr.rb → consumer_groups/virtual_partitions/distributors/consistent.rb} +18 -33
- data/lib/karafka/pro/processing/filters/base.rb +3 -61
- data/lib/karafka/pro/processing/partitioner.rb +2 -57
- data/lib/karafka/pro/processing/schedulers/base.rb +10 -6
- data/lib/karafka/pro/processing/schedulers/default.rb +6 -5
- data/lib/karafka/pro/recurring_tasks/executor.rb +1 -2
- data/lib/karafka/pro/routing/features/{active_job → consumer_groups/active_job}/builder.rb +20 -18
- data/lib/karafka/pro/routing/features/{inline_insights/config.rb → consumer_groups/active_job.rb} +5 -9
- data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/config.rb +53 -0
- data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/contracts/topic.rb +91 -0
- data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/topic.rb +90 -0
- data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator.rb +50 -0
- data/lib/karafka/pro/routing/features/{patterns/contracts/consumer_group.rb → consumer_groups/dead_letter_queue/contracts/topic.rb} +25 -30
- data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue/topic.rb +70 -0
- data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue.rb +46 -0
- data/lib/karafka/pro/routing/features/{direct_assignments → consumer_groups/delaying}/config.rb +6 -4
- data/lib/karafka/pro/routing/features/{patterns/contracts/pattern.rb → consumer_groups/delaying/contracts/topic.rb} +13 -16
- data/lib/karafka/pro/routing/features/consumer_groups/delaying/topic.rb +85 -0
- data/lib/karafka/pro/routing/features/{adaptive_iterator/config.rb → consumer_groups/delaying.rb} +8 -11
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/config.rb +46 -0
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/consumer_group.rb +68 -0
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/topic.rb +125 -0
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +97 -0
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/topic.rb +97 -0
- data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments.rb +44 -0
- data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/config.rb +51 -0
- data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/contracts/topic.rb +58 -0
- data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/topic.rb +80 -0
- data/lib/karafka/pro/routing/features/consumer_groups/inline_insights.rb +45 -0
- data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/config.rb +47 -0
- data/lib/karafka/pro/routing/features/{multiplexing/patches/contracts/consumer_group.rb → consumer_groups/long_running_job/contracts/topic.rb} +13 -15
- data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/topic.rb +72 -0
- data/lib/karafka/pro/routing/features/{long_running_job.rb → consumer_groups/long_running_job.rb} +6 -4
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/config.rb +58 -0
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/routing.rb +83 -0
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/topic.rb +148 -0
- data/lib/karafka/pro/routing/features/{delaying/contracts/topic.rb → consumer_groups/multiplexing/patches/contracts/consumer_group.rb} +19 -14
- data/lib/karafka/pro/routing/features/{multiplexing/subscription_group.rb → consumer_groups/multiplexing/proxy.rb} +17 -23
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/subscription_group.rb +68 -0
- data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/multiplexing}/subscription_groups_builder.rb +16 -14
- data/lib/karafka/pro/routing/features/consumer_groups/multiplexing.rb +85 -0
- data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job/topic.rb +51 -0
- data/lib/karafka/pro/routing/features/{non_blocking_job.rb → consumer_groups/non_blocking_job.rb} +15 -13
- data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/config.rb +52 -0
- data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/contracts/topic.rb +59 -0
- data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +93 -0
- data/lib/karafka/pro/routing/features/{offset_metadata.rb → consumer_groups/offset_metadata.rb} +16 -14
- data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/builder.rb +74 -0
- data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/parallel_segments}/config.rb +13 -15
- data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +110 -0
- data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/contracts/consumer_group.rb +74 -0
- data/lib/karafka/pro/routing/features/{parallel_segments → consumer_groups/parallel_segments}/topic.rb +24 -22
- data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments.rb +51 -0
- data/lib/karafka/pro/routing/features/{patterns → consumer_groups/patterns}/builder.rb +15 -13
- data/lib/karafka/pro/routing/features/{offset_metadata/contracts/topic.rb → consumer_groups/patterns/config.rb} +28 -13
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +91 -0
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/consumer_group.rb +83 -0
- data/lib/karafka/pro/routing/features/{parallel_segments.rb → consumer_groups/patterns/contracts/pattern.rb} +24 -10
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/topic.rb +58 -0
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +98 -0
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +114 -0
- data/lib/karafka/pro/routing/features/{recurring_tasks/contracts/topic.rb → consumer_groups/patterns/patterns.rb} +12 -13
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/topic.rb +78 -0
- data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +72 -0
- data/lib/karafka/pro/routing/features/consumer_groups/patterns.rb +52 -0
- data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/config.rb +56 -0
- data/lib/karafka/pro/routing/features/{direct_assignments/contracts/consumer_group.rb → consumer_groups/periodic_job/contracts/topic.rb} +17 -22
- data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +122 -0
- data/lib/karafka/pro/routing/features/consumer_groups/periodic_job.rb +46 -0
- data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +150 -0
- data/lib/karafka/pro/routing/features/{swarm → consumer_groups/recurring_tasks}/config.rb +7 -8
- data/lib/karafka/pro/routing/features/{inline_insights → consumer_groups/recurring_tasks}/contracts/topic.rb +14 -13
- data/lib/karafka/pro/routing/features/{scheduled_messages → consumer_groups/recurring_tasks}/proxy.rb +6 -4
- data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/topic.rb +72 -0
- data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks.rb +44 -0
- data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +154 -0
- data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/config.rb +47 -0
- data/lib/karafka/pro/routing/features/{long_running_job → consumer_groups/scheduled_messages}/contracts/topic.rb +14 -12
- data/lib/karafka/pro/routing/features/{delaying/config.rb → consumer_groups/scheduled_messages/proxy.rb} +6 -4
- data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +72 -0
- data/lib/karafka/pro/routing/features/{recurring_tasks/proxy.rb → consumer_groups/scheduled_messages.rb} +3 -4
- data/lib/karafka/pro/routing/features/{non_blocking_job/topic.rb → consumer_groups/swarm/config.rb} +9 -8
- data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/routing.rb +94 -0
- data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/topic.rb +95 -0
- data/lib/karafka/pro/routing/features/consumer_groups/swarm/topic.rb +105 -0
- data/lib/karafka/pro/routing/features/consumer_groups/swarm.rb +58 -0
- data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/config.rb +69 -0
- data/lib/karafka/pro/routing/features/{parallel_segments/contracts/consumer_group.rb → consumer_groups/virtual_partitions/contracts/topic.rb} +21 -18
- data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +101 -0
- data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions.rb +46 -0
- data/lib/karafka/pro/routing/features/{scheduled_messages.rb → consumer_groups.rb} +3 -2
- data/lib/karafka/pro/routing/features/expiring/topic.rb +4 -4
- data/lib/karafka/pro/routing/features/filtering/topic.rb +3 -3
- data/lib/karafka/pro/routing/features/pausing/topic.rb +3 -3
- data/lib/karafka/pro/routing/features/throttling/topic.rb +4 -4
- data/lib/karafka/pro/setup/defaults_injector.rb +70 -0
- data/lib/karafka/pro/swarm/liveness_listener.rb +22 -10
- data/lib/karafka/processing/consumer_groups/coordinator.rb +221 -0
- data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +69 -0
- data/lib/karafka/processing/consumer_groups/executor.rb +220 -0
- data/lib/karafka/processing/consumer_groups/executors_buffer.rb +94 -0
- data/lib/karafka/processing/consumer_groups/expansions_selector.rb +26 -0
- data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +47 -0
- data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +23 -0
- data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +132 -0
- data/lib/karafka/processing/consumer_groups/jobs/consume.rb +52 -0
- data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +34 -0
- data/lib/karafka/processing/consumer_groups/jobs/idle.rb +33 -0
- data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +34 -0
- data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +32 -0
- data/lib/karafka/processing/consumer_groups/jobs_builder.rb +36 -0
- data/lib/karafka/processing/consumer_groups/partitioner.rb +28 -0
- data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +48 -0
- data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +25 -0
- data/lib/karafka/processing/consumer_groups/strategies/base.rb +65 -0
- data/lib/karafka/processing/consumer_groups/strategies/default.rb +218 -0
- data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +157 -0
- data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +72 -0
- data/lib/karafka/processing/consumer_groups/strategies/mom.rb +33 -0
- data/lib/karafka/processing/consumer_groups/strategy_selector.rb +53 -0
- data/lib/karafka/processing/coordinator.rb +4 -211
- data/lib/karafka/processing/coordinators_buffer.rb +4 -59
- data/lib/karafka/processing/jobs_queue.rb +12 -4
- data/lib/karafka/processing/partitioner.rb +4 -18
- data/lib/karafka/processing/schedulers/default.rb +2 -1
- data/lib/karafka/processing/strategy_selector.rb +4 -42
- data/lib/karafka/processing/worker.rb +8 -4
- data/lib/karafka/processing/workers_pool.rb +158 -0
- data/lib/karafka/routing/builder.rb +12 -12
- data/lib/karafka/routing/contracts/routing.rb +3 -4
- data/lib/karafka/routing/features/base/expander.rb +5 -5
- data/lib/karafka/routing/features/consumer_groups/active_job/builder.rb +35 -0
- data/lib/karafka/routing/features/consumer_groups/active_job/config.rb +17 -0
- data/lib/karafka/routing/features/consumer_groups/active_job/contracts/topic.rb +44 -0
- data/lib/karafka/routing/features/consumer_groups/active_job/proxy.rb +16 -0
- data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +50 -0
- data/lib/karafka/routing/features/consumer_groups/active_job.rb +15 -0
- data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/config.rb +39 -0
- data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/contracts/topic.rb +58 -0
- data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/topic.rb +76 -0
- data/lib/karafka/routing/features/consumer_groups/dead_letter_queue.rb +18 -0
- data/lib/karafka/routing/features/consumer_groups/eofed/config.rb +17 -0
- data/lib/karafka/routing/features/consumer_groups/eofed/contracts/topic.rb +39 -0
- data/lib/karafka/routing/features/consumer_groups/eofed/topic.rb +42 -0
- data/lib/karafka/routing/features/consumer_groups/eofed.rb +16 -0
- data/lib/karafka/routing/features/consumer_groups/inline_insights/config.rb +17 -0
- data/lib/karafka/routing/features/consumer_groups/inline_insights/contracts/topic.rb +27 -0
- data/lib/karafka/routing/features/consumer_groups/inline_insights/topic.rb +42 -0
- data/lib/karafka/routing/features/consumer_groups/inline_insights.rb +42 -0
- data/lib/karafka/routing/features/consumer_groups/manual_offset_management/config.rb +17 -0
- data/lib/karafka/routing/features/consumer_groups/manual_offset_management/contracts/topic.rb +27 -0
- data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +46 -0
- data/lib/karafka/routing/features/consumer_groups/manual_offset_management.rb +20 -0
- data/lib/karafka/routing/features/consumer_groups.rb +12 -0
- data/lib/karafka/routing/features/declaratives/contracts/topic.rb +4 -19
- data/lib/karafka/routing/features/declaratives/topic.rb +30 -14
- data/lib/karafka/routing/features/deserializers/topic.rb +3 -3
- data/lib/karafka/routing/router.rb +2 -2
- data/lib/karafka/routing/subscription_group.rb +18 -9
- data/lib/karafka/routing/topic.rb +25 -11
- data/lib/karafka/runner.rb +17 -17
- data/lib/karafka/server.rb +28 -6
- data/lib/karafka/setup/attributes_map.rb +2 -0
- data/lib/karafka/setup/config.rb +64 -15
- data/lib/karafka/setup/config_proxy.rb +1 -2
- data/lib/karafka/setup/contracts/config.rb +28 -8
- data/lib/karafka/setup/defaults_injector.rb +10 -0
- data/lib/karafka/status.rb +1 -2
- data/lib/karafka/swarm/liveness_listener.rb +7 -0
- data/lib/karafka/swarm/manager.rb +7 -7
- data/lib/karafka/swarm/node.rb +8 -0
- data/lib/karafka/swarm/supervisor.rb +9 -1
- data/lib/karafka/templates/karafka.rb.erb +11 -5
- data/lib/karafka/version.rb +1 -1
- metadata +237 -224
- data/lib/karafka/connection/rebalance_manager.rb +0 -116
- data/lib/karafka/instrumentation/callbacks/error.rb +0 -52
- data/lib/karafka/instrumentation/callbacks/rebalance.rb +0 -84
- data/lib/karafka/instrumentation/callbacks/statistics.rb +0 -55
- data/lib/karafka/pro/processing/adaptive_iterator/consumer.rb +0 -79
- data/lib/karafka/pro/processing/adaptive_iterator/tracker.rb +0 -92
- data/lib/karafka/pro/processing/collapser.rb +0 -79
- data/lib/karafka/pro/processing/coordinator.rb +0 -197
- data/lib/karafka/pro/processing/coordinators/errors_tracker.rb +0 -119
- data/lib/karafka/pro/processing/coordinators/filters_applier.rb +0 -152
- data/lib/karafka/pro/processing/coordinators/virtual_offset_manager.rb +0 -207
- data/lib/karafka/pro/processing/expansions_selector.rb +0 -52
- data/lib/karafka/pro/processing/filters/delayer.rb +0 -87
- data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +0 -95
- data/lib/karafka/pro/processing/filters/throttler.rb +0 -101
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +0 -74
- data/lib/karafka/pro/processing/jobs/eofed_non_blocking.rb +0 -51
- data/lib/karafka/pro/processing/jobs_builder.rb +0 -90
- data/lib/karafka/pro/processing/offset_metadata/consumer.rb +0 -61
- data/lib/karafka/pro/processing/offset_metadata/fetcher.rb +0 -149
- data/lib/karafka/pro/processing/offset_metadata/listener.rb +0 -63
- data/lib/karafka/pro/processing/parallel_segments/filters/base.rb +0 -98
- data/lib/karafka/pro/processing/parallel_segments/filters/default.rb +0 -110
- data/lib/karafka/pro/processing/parallel_segments/filters/mom.rb +0 -91
- data/lib/karafka/pro/processing/periodic_job/consumer.rb +0 -85
- data/lib/karafka/pro/processing/piping/consumer.rb +0 -149
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +0 -94
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +0 -87
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +0 -85
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +0 -81
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +0 -85
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +0 -79
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +0 -84
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +0 -86
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +0 -54
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +0 -101
- data/lib/karafka/pro/processing/strategies/base.rb +0 -43
- data/lib/karafka/pro/processing/strategies/default.rb +0 -416
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +0 -280
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +0 -90
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +0 -92
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +0 -60
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +0 -58
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +0 -92
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +0 -58
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +0 -57
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +0 -95
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +0 -56
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +0 -91
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +0 -54
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +0 -57
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +0 -141
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +0 -57
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +0 -114
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +0 -89
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +0 -87
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +0 -57
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +0 -56
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +0 -96
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +0 -54
- data/lib/karafka/pro/processing/strategies/vp/default.rb +0 -192
- data/lib/karafka/pro/processing/strategies.rb +0 -39
- data/lib/karafka/pro/processing/strategy_selector.rb +0 -102
- data/lib/karafka/pro/processing/subscription_groups_coordinator.rb +0 -68
- data/lib/karafka/pro/processing/virtual_partitions/distributors/balanced.rb +0 -77
- data/lib/karafka/pro/routing/features/active_job.rb +0 -43
- data/lib/karafka/pro/routing/features/adaptive_iterator/contracts/topic.rb +0 -89
- data/lib/karafka/pro/routing/features/adaptive_iterator/topic.rb +0 -88
- data/lib/karafka/pro/routing/features/adaptive_iterator.rb +0 -48
- data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +0 -74
- data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +0 -68
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +0 -44
- data/lib/karafka/pro/routing/features/delaying/topic.rb +0 -83
- data/lib/karafka/pro/routing/features/delaying.rb +0 -46
- data/lib/karafka/pro/routing/features/direct_assignments/contracts/topic.rb +0 -123
- data/lib/karafka/pro/routing/features/direct_assignments/subscription_group.rb +0 -95
- data/lib/karafka/pro/routing/features/direct_assignments/topic.rb +0 -95
- data/lib/karafka/pro/routing/features/direct_assignments.rb +0 -42
- data/lib/karafka/pro/routing/features/inline_insights/topic.rb +0 -78
- data/lib/karafka/pro/routing/features/inline_insights.rb +0 -43
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +0 -45
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +0 -70
- data/lib/karafka/pro/routing/features/multiplexing/contracts/routing.rb +0 -81
- data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +0 -146
- data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +0 -58
- data/lib/karafka/pro/routing/features/multiplexing.rb +0 -83
- data/lib/karafka/pro/routing/features/offset_metadata/config.rb +0 -50
- data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +0 -91
- data/lib/karafka/pro/routing/features/parallel_segments/builder.rb +0 -72
- data/lib/karafka/pro/routing/features/parallel_segments/config.rb +0 -52
- data/lib/karafka/pro/routing/features/parallel_segments/consumer_group.rb +0 -108
- data/lib/karafka/pro/routing/features/patterns/config.rb +0 -71
- data/lib/karafka/pro/routing/features/patterns/consumer_group.rb +0 -89
- data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +0 -56
- data/lib/karafka/pro/routing/features/patterns/detector.rb +0 -96
- data/lib/karafka/pro/routing/features/patterns/pattern.rb +0 -112
- data/lib/karafka/pro/routing/features/patterns/topic.rb +0 -76
- data/lib/karafka/pro/routing/features/patterns/topics.rb +0 -70
- data/lib/karafka/pro/routing/features/patterns.rb +0 -50
- data/lib/karafka/pro/routing/features/periodic_job/config.rb +0 -54
- data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +0 -59
- data/lib/karafka/pro/routing/features/periodic_job/topic.rb +0 -120
- data/lib/karafka/pro/routing/features/periodic_job.rb +0 -44
- data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +0 -148
- data/lib/karafka/pro/routing/features/recurring_tasks/config.rb +0 -45
- data/lib/karafka/pro/routing/features/recurring_tasks/topic.rb +0 -70
- data/lib/karafka/pro/routing/features/recurring_tasks.rb +0 -42
- data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +0 -152
- data/lib/karafka/pro/routing/features/scheduled_messages/config.rb +0 -45
- data/lib/karafka/pro/routing/features/scheduled_messages/contracts/topic.rb +0 -55
- data/lib/karafka/pro/routing/features/scheduled_messages/topic.rb +0 -70
- data/lib/karafka/pro/routing/features/swarm/contracts/routing.rb +0 -92
- data/lib/karafka/pro/routing/features/swarm/contracts/topic.rb +0 -93
- data/lib/karafka/pro/routing/features/swarm/topic.rb +0 -103
- data/lib/karafka/pro/routing/features/swarm.rb +0 -56
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +0 -67
- data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +0 -73
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +0 -99
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +0 -44
- data/lib/karafka/processing/executor.rb +0 -216
- data/lib/karafka/processing/executors_buffer.rb +0 -90
- data/lib/karafka/processing/expansions_selector.rb +0 -22
- data/lib/karafka/processing/inline_insights/consumer.rb +0 -43
- data/lib/karafka/processing/inline_insights/listener.rb +0 -19
- data/lib/karafka/processing/inline_insights/tracker.rb +0 -129
- data/lib/karafka/processing/jobs/consume.rb +0 -47
- data/lib/karafka/processing/jobs/eofed.rb +0 -29
- data/lib/karafka/processing/jobs/idle.rb +0 -31
- data/lib/karafka/processing/jobs/revoked.rb +0 -29
- data/lib/karafka/processing/jobs/shutdown.rb +0 -30
- data/lib/karafka/processing/jobs_builder.rb +0 -34
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +0 -44
- data/lib/karafka/processing/strategies/aj_mom.rb +0 -21
- data/lib/karafka/processing/strategies/base.rb +0 -61
- data/lib/karafka/processing/strategies/default.rb +0 -214
- data/lib/karafka/processing/strategies/dlq.rb +0 -153
- data/lib/karafka/processing/strategies/dlq_mom.rb +0 -68
- data/lib/karafka/processing/strategies/mom.rb +0 -29
- data/lib/karafka/processing/workers_batch.rb +0 -29
- data/lib/karafka/routing/features/active_job/builder.rb +0 -33
- data/lib/karafka/routing/features/active_job/config.rb +0 -15
- data/lib/karafka/routing/features/active_job/contracts/topic.rb +0 -42
- data/lib/karafka/routing/features/active_job/proxy.rb +0 -14
- data/lib/karafka/routing/features/active_job/topic.rb +0 -48
- data/lib/karafka/routing/features/active_job.rb +0 -13
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +0 -37
- data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +0 -56
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +0 -74
- data/lib/karafka/routing/features/dead_letter_queue.rb +0 -16
- data/lib/karafka/routing/features/declaratives/config.rb +0 -18
- data/lib/karafka/routing/features/eofed/config.rb +0 -15
- data/lib/karafka/routing/features/eofed/contracts/topic.rb +0 -37
- data/lib/karafka/routing/features/eofed/topic.rb +0 -40
- data/lib/karafka/routing/features/eofed.rb +0 -14
- data/lib/karafka/routing/features/inline_insights/config.rb +0 -15
- data/lib/karafka/routing/features/inline_insights/contracts/topic.rb +0 -25
- data/lib/karafka/routing/features/inline_insights/topic.rb +0 -40
- data/lib/karafka/routing/features/inline_insights.rb +0 -40
- data/lib/karafka/routing/features/manual_offset_management/config.rb +0 -15
- data/lib/karafka/routing/features/manual_offset_management/contracts/topic.rb +0 -25
- data/lib/karafka/routing/features/manual_offset_management/topic.rb +0 -44
- data/lib/karafka/routing/features/manual_offset_management.rb +0 -18
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Karafka Pro - Source Available Commercial Software
|
|
4
|
-
# Copyright (c) 2017-present Maciej Mensfeld. All rights reserved.
|
|
5
|
-
#
|
|
6
|
-
# This software is NOT open source. It is source-available commercial software
|
|
7
|
-
# requiring a paid license for use. It is NOT covered by LGPL.
|
|
8
|
-
#
|
|
9
|
-
# The author retains all right, title, and interest in this software,
|
|
10
|
-
# including all copyrights, patents, and other intellectual property rights.
|
|
11
|
-
# No patent rights are granted under this license.
|
|
12
|
-
#
|
|
13
|
-
# PROHIBITED:
|
|
14
|
-
# - Use without a valid commercial license
|
|
15
|
-
# - Redistribution, modification, or derivative works without authorization
|
|
16
|
-
# - Reverse engineering, decompilation, or disassembly of this software
|
|
17
|
-
# - Use as training data for AI/ML models or inclusion in datasets
|
|
18
|
-
# - Scraping, crawling, or automated collection for any purpose
|
|
19
|
-
#
|
|
20
|
-
# PERMITTED:
|
|
21
|
-
# - Reading, referencing, and linking for personal or commercial use
|
|
22
|
-
# - Runtime retrieval by AI assistants, coding agents, and RAG systems
|
|
23
|
-
# for the purpose of providing contextual help to Karafka users
|
|
24
|
-
#
|
|
25
|
-
# Receipt, viewing, or possession of this software does not convey or
|
|
26
|
-
# imply any license or right beyond those expressly stated above.
|
|
27
|
-
#
|
|
28
|
-
# License: https://karafka.io/docs/Pro-License-Comm/
|
|
29
|
-
# Contact: contact@karafka.io
|
|
30
|
-
|
|
31
|
-
module Karafka
|
|
32
|
-
module Pro
|
|
33
|
-
module Routing
|
|
34
|
-
module Features
|
|
35
|
-
class VirtualPartitions < Base
|
|
36
|
-
# Topic extensions to be able to manage virtual partitions feature
|
|
37
|
-
module Topic
|
|
38
|
-
# This method calls the parent class initializer and then sets up the
|
|
39
|
-
# extra instance variable to nil. The explicit initialization
|
|
40
|
-
# to nil is included as an optimization for Ruby's object shapes system,
|
|
41
|
-
# which improves memory layout and access performance.
|
|
42
|
-
def initialize(...)
|
|
43
|
-
super
|
|
44
|
-
@virtual_partitions = nil
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# @param max_partitions [Integer] max number of virtual partitions that can come out of
|
|
48
|
-
# the single distribution flow. When set to more than the Karafka threading, will
|
|
49
|
-
# create more work than workers. When less, can ensure we have spare resources to
|
|
50
|
-
# process other things in parallel.
|
|
51
|
-
# @param partitioner [nil, #call] nil or callable partitioner
|
|
52
|
-
# @param offset_metadata_strategy [Symbol] how we should match the metadata for the
|
|
53
|
-
# offset. `:exact` will match the offset matching metadata and `:current` will select
|
|
54
|
-
# the most recently reported metadata
|
|
55
|
-
# @param reducer [nil, #call] reducer for VPs key. It allows for using a custom
|
|
56
|
-
# reducer to achieve enhanced parallelization when the default reducer is not enough.
|
|
57
|
-
# @param distribution [Symbol] the strategy to use for virtual partitioning. Can be
|
|
58
|
-
# either `:consistent` or `:balanced`. The `:balanced` strategy ensures balanced
|
|
59
|
-
# distribution of work across available workers while maintaining message order
|
|
60
|
-
# within groups.
|
|
61
|
-
# @return [VirtualPartitions] method that allows to set the virtual partitions details
|
|
62
|
-
# during the routing configuration and then allows to retrieve it
|
|
63
|
-
def virtual_partitions(
|
|
64
|
-
max_partitions: Karafka::App.config.concurrency,
|
|
65
|
-
partitioner: nil,
|
|
66
|
-
offset_metadata_strategy: :current,
|
|
67
|
-
reducer: nil,
|
|
68
|
-
distribution: :consistent
|
|
69
|
-
)
|
|
70
|
-
@virtual_partitions ||= Config.new(
|
|
71
|
-
active: !partitioner.nil?,
|
|
72
|
-
max_partitions: max_partitions,
|
|
73
|
-
partitioner: partitioner,
|
|
74
|
-
offset_metadata_strategy: offset_metadata_strategy,
|
|
75
|
-
# If no reducer provided, we use this one. It just runs a modulo on the sum of
|
|
76
|
-
# a stringified version, providing fairly good distribution.
|
|
77
|
-
reducer: reducer || ->(virtual_key) { virtual_key.to_s.sum % max_partitions },
|
|
78
|
-
distribution: distribution
|
|
79
|
-
)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# @return [Boolean] are virtual partitions enabled for given topic
|
|
83
|
-
def virtual_partitions?
|
|
84
|
-
virtual_partitions.active?
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# @return [Hash] topic with all its native configuration options plus manual offset
|
|
88
|
-
# management namespace settings
|
|
89
|
-
def to_h
|
|
90
|
-
super.merge(
|
|
91
|
-
virtual_partitions: virtual_partitions.to_h
|
|
92
|
-
).freeze
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Karafka Pro - Source Available Commercial Software
|
|
4
|
-
# Copyright (c) 2017-present Maciej Mensfeld. All rights reserved.
|
|
5
|
-
#
|
|
6
|
-
# This software is NOT open source. It is source-available commercial software
|
|
7
|
-
# requiring a paid license for use. It is NOT covered by LGPL.
|
|
8
|
-
#
|
|
9
|
-
# The author retains all right, title, and interest in this software,
|
|
10
|
-
# including all copyrights, patents, and other intellectual property rights.
|
|
11
|
-
# No patent rights are granted under this license.
|
|
12
|
-
#
|
|
13
|
-
# PROHIBITED:
|
|
14
|
-
# - Use without a valid commercial license
|
|
15
|
-
# - Redistribution, modification, or derivative works without authorization
|
|
16
|
-
# - Reverse engineering, decompilation, or disassembly of this software
|
|
17
|
-
# - Use as training data for AI/ML models or inclusion in datasets
|
|
18
|
-
# - Scraping, crawling, or automated collection for any purpose
|
|
19
|
-
#
|
|
20
|
-
# PERMITTED:
|
|
21
|
-
# - Reading, referencing, and linking for personal or commercial use
|
|
22
|
-
# - Runtime retrieval by AI assistants, coding agents, and RAG systems
|
|
23
|
-
# for the purpose of providing contextual help to Karafka users
|
|
24
|
-
#
|
|
25
|
-
# Receipt, viewing, or possession of this software does not convey or
|
|
26
|
-
# imply any license or right beyond those expressly stated above.
|
|
27
|
-
#
|
|
28
|
-
# License: https://karafka.io/docs/Pro-License-Comm/
|
|
29
|
-
# Contact: contact@karafka.io
|
|
30
|
-
|
|
31
|
-
module Karafka
|
|
32
|
-
module Pro
|
|
33
|
-
module Routing
|
|
34
|
-
module Features
|
|
35
|
-
# Virtual Partitions feature config and DSL namespace.
|
|
36
|
-
#
|
|
37
|
-
# Virtual Partitions allow you to parallelize the processing of data from a single
|
|
38
|
-
# partition. This can drastically increase throughput when IO operations are involved.
|
|
39
|
-
class VirtualPartitions < Base
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
# Namespace that encapsulates all the logic related to processing data.
|
|
5
|
-
module Processing
|
|
6
|
-
# Executors:
|
|
7
|
-
# - run consumers code (for `#call`) or run given preparation / teardown operations when needed
|
|
8
|
-
# from separate threads.
|
|
9
|
-
# - they re-create consumer instances in case of partitions that were revoked and assigned
|
|
10
|
-
# back.
|
|
11
|
-
#
|
|
12
|
-
# @note Executors are not removed after partition is revoked. They are not that big and will
|
|
13
|
-
# be re-used in case of a re-claim
|
|
14
|
-
#
|
|
15
|
-
# @note Since given consumer can run various operations, executor manages that and its
|
|
16
|
-
# lifecycle. There are following types of operations with appropriate before/after, etc:
|
|
17
|
-
#
|
|
18
|
-
# - consume - primary operation related to running user consumption code
|
|
19
|
-
# - idle - cleanup job that runs on idle runs where no messages would be passed to the end
|
|
20
|
-
# user. This is used for complex flows with filters, etc
|
|
21
|
-
# - revoked - runs after the partition was revoked
|
|
22
|
-
# - shutdown - runs when process is going to shutdown
|
|
23
|
-
class Executor
|
|
24
|
-
extend Forwardable
|
|
25
|
-
include Helpers::ConfigImporter.new(
|
|
26
|
-
strategy_selector: %i[internal processing strategy_selector],
|
|
27
|
-
expansions_selector: %i[internal processing expansions_selector]
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
def_delegators :@coordinator, :topic, :partition
|
|
31
|
-
|
|
32
|
-
# @return [String] unique id that we use to ensure, that we use for state tracking
|
|
33
|
-
attr_reader :id
|
|
34
|
-
|
|
35
|
-
# @return [String] subscription group id to which a given executor belongs
|
|
36
|
-
attr_reader :group_id
|
|
37
|
-
|
|
38
|
-
# @return [Karafka::Messages::Messages] messages batch
|
|
39
|
-
attr_reader :messages
|
|
40
|
-
|
|
41
|
-
# @return [Karafka::Processing::Coordinator] coordinator for this executor
|
|
42
|
-
attr_reader :coordinator
|
|
43
|
-
|
|
44
|
-
# @param group_id [String] id of the subscription group to which the executor belongs
|
|
45
|
-
# @param client [Karafka::Connection::Client] kafka client
|
|
46
|
-
# @param coordinator [Karafka::Processing::Coordinator]
|
|
47
|
-
def initialize(group_id, client, coordinator)
|
|
48
|
-
@id = SecureRandom.hex(6)
|
|
49
|
-
@group_id = group_id
|
|
50
|
-
@client = client
|
|
51
|
-
@coordinator = coordinator
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Allows us to prepare the consumer in the listener thread prior to the job being send to
|
|
55
|
-
# be scheduled. It also allows to run some code that is time sensitive and cannot wait in the
|
|
56
|
-
# queue as it could cause starvation.
|
|
57
|
-
#
|
|
58
|
-
# @param messages [Array<Karafka::Messages::Message>]
|
|
59
|
-
def before_schedule_consume(messages)
|
|
60
|
-
# Recreate consumer with each batch if persistence is not enabled
|
|
61
|
-
# We reload the consumers with each batch instead of relying on some external signals
|
|
62
|
-
# when needed for consistency. That way devs may have it on or off and not in this
|
|
63
|
-
# middle state, where re-creation of a consumer instance would occur only sometimes
|
|
64
|
-
@consumer = nil unless topic.consumer_persistence
|
|
65
|
-
|
|
66
|
-
# First we build messages batch...
|
|
67
|
-
consumer.messages = Messages::Builders::Messages.call(
|
|
68
|
-
messages,
|
|
69
|
-
topic,
|
|
70
|
-
partition,
|
|
71
|
-
# the moment we've received the batch or actually the moment we've enqueued it,
|
|
72
|
-
# but good enough
|
|
73
|
-
Time.now
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
consumer.on_before_schedule_consume
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Runs setup and warm-up code in the worker prior to running the consumption
|
|
80
|
-
def before_consume
|
|
81
|
-
consumer.on_before_consume
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Runs the wrap/around execution context appropriate for a given action
|
|
85
|
-
# @param action [Symbol] action execution wrapped with our block
|
|
86
|
-
def wrap(action, &)
|
|
87
|
-
consumer.on_wrap(action, &)
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Runs consumer data processing against given batch and handles failures and errors.
|
|
91
|
-
def consume
|
|
92
|
-
# We run the consumer client logic...
|
|
93
|
-
consumer.on_consume
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Runs consumer after consumption code
|
|
97
|
-
def after_consume
|
|
98
|
-
consumer.on_after_consume
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
# Runs the code needed before idle work is scheduled
|
|
102
|
-
def before_schedule_idle
|
|
103
|
-
consumer.on_before_schedule_idle
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
# Runs consumer idle operations
|
|
107
|
-
# This may include house-keeping or other state management changes that can occur but that
|
|
108
|
-
# not mean there are any new messages available for the end user to process
|
|
109
|
-
def idle
|
|
110
|
-
consumer.on_idle
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
# Runs the code needed before eofed work is scheduled
|
|
114
|
-
def before_schedule_eofed
|
|
115
|
-
consumer.on_before_schedule_eofed
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Runs consumed eofed operation.
|
|
119
|
-
# This may run even when there were no messages received prior. This will however not
|
|
120
|
-
# run when eof is received together with messages as in such case `#consume` will run
|
|
121
|
-
def eofed
|
|
122
|
-
consumer.on_eofed
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
# Runs code needed before revoked job is scheduled
|
|
126
|
-
def before_schedule_revoked
|
|
127
|
-
consumer.on_before_schedule_revoked if @consumer
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Runs the controller `#revoked` method that should be triggered when a given consumer is
|
|
131
|
-
# no longer needed due to partitions reassignment.
|
|
132
|
-
#
|
|
133
|
-
# @note Clearing the consumer will ensure, that if we get the partition back, it will be
|
|
134
|
-
# handled with a consumer with a clean state.
|
|
135
|
-
#
|
|
136
|
-
# @note We run it only when consumer was present, because presence indicates, that at least
|
|
137
|
-
# a single message has been consumed.
|
|
138
|
-
#
|
|
139
|
-
# @note We do not reset the consumer but we indicate need for recreation instead, because
|
|
140
|
-
# after the revocation, there still may be `#after_consume` running that needs a given
|
|
141
|
-
# consumer instance.
|
|
142
|
-
def revoked
|
|
143
|
-
consumer.on_revoked if @consumer
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
# Runs code needed before shutdown job is scheduled
|
|
147
|
-
def before_schedule_shutdown
|
|
148
|
-
consumer.on_before_schedule_shutdown if @consumer
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# Runs the controller `#shutdown` method that should be triggered when a given consumer is
|
|
152
|
-
# no longer needed as we're closing the process.
|
|
153
|
-
#
|
|
154
|
-
# @note While we do not need to clear the consumer here, it's a good habit to clean after
|
|
155
|
-
# work is done.
|
|
156
|
-
def shutdown
|
|
157
|
-
# There is a case, where the consumer no longer exists because it was revoked, in case like
|
|
158
|
-
# that we do not build a new instance and shutdown should not be triggered.
|
|
159
|
-
consumer.on_shutdown if @consumer
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
private
|
|
163
|
-
|
|
164
|
-
# @return [Object] cached consumer instance
|
|
165
|
-
def consumer
|
|
166
|
-
@consumer ||= begin
|
|
167
|
-
topic = @coordinator.topic
|
|
168
|
-
|
|
169
|
-
strategy = strategy_selector.find(topic)
|
|
170
|
-
|
|
171
|
-
consumer = topic.consumer_class.new
|
|
172
|
-
# We use singleton class as the same consumer class may be used to process different
|
|
173
|
-
# topics with different settings
|
|
174
|
-
consumer.singleton_class.include(strategy)
|
|
175
|
-
|
|
176
|
-
# Specific features may expand consumer API beyond the injected strategy. The difference
|
|
177
|
-
# here is that strategy impacts the flow of states while extra APIs just provide some
|
|
178
|
-
# extra methods with informations, etc but do no deviate the flow behavior
|
|
179
|
-
expansions = expansions_selector.find(topic)
|
|
180
|
-
expansions.each { |expansion| consumer.singleton_class.include(expansion) }
|
|
181
|
-
|
|
182
|
-
consumer.client = @client
|
|
183
|
-
consumer.coordinator = @coordinator
|
|
184
|
-
# We assign producer only when not available already. It may already be available if
|
|
185
|
-
# user redefined the `#producer` method for example. This can be useful for example when
|
|
186
|
-
# having a multi-cluster setup and using a totally custom producer
|
|
187
|
-
consumer.producer ||= Karafka::App.producer
|
|
188
|
-
# Since we have some message-less flows (idle, etc), we initialize consumer with empty
|
|
189
|
-
# messages set. In production we have persistent consumers, so this is not a performance
|
|
190
|
-
# overhead as this will happen only once per consumer lifetime
|
|
191
|
-
consumer.messages = empty_messages
|
|
192
|
-
|
|
193
|
-
# Run the post-initialization hook for users that need to run some actions when consumer
|
|
194
|
-
# is built and ready (all basic state and info).
|
|
195
|
-
# Users should **not** overwrite the `#initialize` because it won't have all the needed
|
|
196
|
-
# data assigned yet.
|
|
197
|
-
consumer.on_initialized
|
|
198
|
-
|
|
199
|
-
consumer
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
# Initializes the messages set in case given operation would happen before any processing
|
|
204
|
-
# This prevents us from having no messages object at all as the messages object and
|
|
205
|
-
# its metadata may be used for statistics
|
|
206
|
-
def empty_messages
|
|
207
|
-
Messages::Builders::Messages.call(
|
|
208
|
-
[],
|
|
209
|
-
topic,
|
|
210
|
-
partition,
|
|
211
|
-
Time.now
|
|
212
|
-
)
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
end
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
module Processing
|
|
5
|
-
# Buffer for executors of a given subscription group. It wraps around the concept of building
|
|
6
|
-
# and caching them, so we can re-use them instead of creating new each time.
|
|
7
|
-
class ExecutorsBuffer
|
|
8
|
-
include Helpers::ConfigImporter.new(
|
|
9
|
-
executor_class: %i[internal processing executor_class]
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
# @param client [Connection::Client]
|
|
13
|
-
# @param subscription_group [Routing::SubscriptionGroup]
|
|
14
|
-
# @return [ExecutorsBuffer]
|
|
15
|
-
def initialize(client, subscription_group)
|
|
16
|
-
@subscription_group = subscription_group
|
|
17
|
-
@client = client
|
|
18
|
-
# We need two layers here to keep track of topics, partitions and processing groups
|
|
19
|
-
@buffer = Hash.new { |h, k| h[k] = Hash.new { |h2, k2| h2[k2] = {} } }
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# Finds or creates an executor based on the provided details
|
|
23
|
-
#
|
|
24
|
-
# @param topic [String] topic name
|
|
25
|
-
# @param partition [Integer] partition number
|
|
26
|
-
# @param parallel_key [String] parallel group key
|
|
27
|
-
# @param coordinator [Karafka::Processing::Coordinator]
|
|
28
|
-
# @return [Executor, Pro::Processing::Executor] consumer executor
|
|
29
|
-
def find_or_create(topic, partition, parallel_key, coordinator)
|
|
30
|
-
@buffer[topic][partition][parallel_key] ||= executor_class.new(
|
|
31
|
-
@subscription_group.id,
|
|
32
|
-
@client,
|
|
33
|
-
coordinator
|
|
34
|
-
)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Finds all existing executors for given topic partition or creates one for it
|
|
38
|
-
# @param topic [String] topic name
|
|
39
|
-
# @param partition [Integer] partition number
|
|
40
|
-
# @param coordinator [Karafka::Processing::Coordinator]
|
|
41
|
-
# @return [Array<Executor, Pro::Processing::Executor>]
|
|
42
|
-
def find_all_or_create(topic, partition, coordinator)
|
|
43
|
-
existing = find_all(topic, partition)
|
|
44
|
-
|
|
45
|
-
return existing unless existing.empty?
|
|
46
|
-
|
|
47
|
-
[find_or_create(topic, partition, 0, coordinator)]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Revokes executors of a given topic partition, so they won't be used anymore for incoming
|
|
51
|
-
# messages
|
|
52
|
-
#
|
|
53
|
-
# @param topic [String] topic name
|
|
54
|
-
# @param partition [Integer] partition number
|
|
55
|
-
def revoke(topic, partition)
|
|
56
|
-
@buffer[topic][partition].clear
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Finds all the executors available for a given topic partition
|
|
60
|
-
#
|
|
61
|
-
# @param topic [String] topic name
|
|
62
|
-
# @param partition [Integer] partition number
|
|
63
|
-
# @return [Array<Executor, Pro::Processing::Executor>] executors in use for this
|
|
64
|
-
# topic + partition
|
|
65
|
-
def find_all(topic, partition)
|
|
66
|
-
@buffer[topic][partition].values
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Iterates over all available executors and yields them together with topic and partition
|
|
70
|
-
# info
|
|
71
|
-
# @yieldparam [Routing::Topic] karafka routing topic object
|
|
72
|
-
# @yieldparam [Integer] partition number
|
|
73
|
-
# @yieldparam [Executor, Pro::Processing::Executor] given executor
|
|
74
|
-
def each
|
|
75
|
-
@buffer.each_value do |partitions|
|
|
76
|
-
partitions.each_value do |executors|
|
|
77
|
-
executors.each_value do |executor|
|
|
78
|
-
yield(executor)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Clears the executors buffer. Useful for critical errors recovery.
|
|
85
|
-
def clear
|
|
86
|
-
@buffer.clear
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
module Processing
|
|
5
|
-
# Selector of appropriate topic setup based features enhancements.
|
|
6
|
-
#
|
|
7
|
-
# Those expansions to the consumer API are NOT about the flow of processing. For this we have
|
|
8
|
-
# strategies. Those are suppose to provide certain extra APIs that user can use to get some
|
|
9
|
-
# extra non-flow related functionalities.
|
|
10
|
-
class ExpansionsSelector
|
|
11
|
-
# @param topic [Karafka::Routing::Topic] topic with settings based on which we find
|
|
12
|
-
# expansions
|
|
13
|
-
# @return [Array<Module>] modules with proper expansions we're suppose to use to enhance the
|
|
14
|
-
# consumer
|
|
15
|
-
def find(topic)
|
|
16
|
-
expansions = []
|
|
17
|
-
expansions << Processing::InlineInsights::Consumer if topic.inline_insights?
|
|
18
|
-
expansions
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
module Processing
|
|
5
|
-
# Namespace of the Inline Insights feature "non routing" related components
|
|
6
|
-
#
|
|
7
|
-
# @note We use both `#insights` because it is the feature name but also `#statistics` to make
|
|
8
|
-
# it consistent with the fact that we publish and operate on statistics. User can pick
|
|
9
|
-
# whichever name they prefer.
|
|
10
|
-
module InlineInsights
|
|
11
|
-
# Module that adds extra methods to the consumer that allow us to fetch the insights
|
|
12
|
-
module Consumer
|
|
13
|
-
# @return [Hash] empty hash or hash with given partition insights if already present
|
|
14
|
-
# @note We cache insights on the consumer, as in some scenarios we may no longer have them
|
|
15
|
-
# inside the Tracker, for example under involuntary revocation, incoming statistics may
|
|
16
|
-
# no longer have lost partition insights. Since we want to be consistent during single
|
|
17
|
-
# batch operations, we want to ensure, that if we have insights they are available
|
|
18
|
-
# throughout the whole processing.
|
|
19
|
-
def insights
|
|
20
|
-
insights = Tracker.find(topic, partition)
|
|
21
|
-
|
|
22
|
-
# If we no longer have new insights but we still have them locally, we can use them
|
|
23
|
-
return @insights if @insights && insights.empty?
|
|
24
|
-
# If insights are still the same, we can use them
|
|
25
|
-
return @insights if @insights.equal?(insights)
|
|
26
|
-
|
|
27
|
-
# If we've received new insights that are not empty, we can cache them
|
|
28
|
-
@insights = insights
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# @return [Boolean] true if there are insights to work with, otherwise false
|
|
32
|
-
def insights?
|
|
33
|
-
!insights.empty?
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
alias_method :statistics, :insights
|
|
37
|
-
alias_method :statistics?, :insights?
|
|
38
|
-
alias_method :inline_insights, :insights
|
|
39
|
-
alias_method :inline_insights?, :insights?
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
module Processing
|
|
5
|
-
module InlineInsights
|
|
6
|
-
# Listener that adds statistics to our inline tracker
|
|
7
|
-
class Listener
|
|
8
|
-
# Adds statistics to the tracker
|
|
9
|
-
# @param event [Karafka::Core::Monitoring::Event] event with statistics
|
|
10
|
-
def on_statistics_emitted(event)
|
|
11
|
-
Tracker.add(
|
|
12
|
-
event[:consumer_group_id],
|
|
13
|
-
event[:statistics]
|
|
14
|
-
)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Karafka
|
|
4
|
-
module Processing
|
|
5
|
-
module InlineInsights
|
|
6
|
-
# Object used to track statistics coming from librdkafka in a way that can be accessible by
|
|
7
|
-
# the consumers
|
|
8
|
-
#
|
|
9
|
-
# We use a single tracker because we do not need state management here as our consumer groups
|
|
10
|
-
# clients identified by statistics name value are unique. On top of that, having a per
|
|
11
|
-
# process one that is a singleton allows us to use tracker easily also from other places like
|
|
12
|
-
# filtering API etc.
|
|
13
|
-
#
|
|
14
|
-
# @note We include cache of 5 minutes for revoked partitions to compensate for cases where
|
|
15
|
-
# when using LRJ a lost partition data would not be present anymore, however we would still
|
|
16
|
-
# be in the processing phase. Since those metrics are published with each `poll`, regular
|
|
17
|
-
# processing is not a subject of this issue. For LRJ we keep the reference. The only case
|
|
18
|
-
# where this could be switched midway is when LRJ is running for an extended period of time
|
|
19
|
-
# after the involuntary revocation. Having a time based cache instead of tracking
|
|
20
|
-
# simplifies the design as we do not have to deal with state tracking, especially since
|
|
21
|
-
# we would have to track also operations running in a revoked state.
|
|
22
|
-
#
|
|
23
|
-
# @note This tracker keeps in memory data about all topics and partitions that it encounters
|
|
24
|
-
# because in case of routing patterns, we may start getting statistics prior to registering
|
|
25
|
-
# given topic via dynamic routing expansions. In such case we would not have insights
|
|
26
|
-
# where they were actually available for us to use.
|
|
27
|
-
#
|
|
28
|
-
# @note Memory usage is negligible as long as we can evict expired data. Single metrics set
|
|
29
|
-
# for a single partition contains around 4KB of data. This means, that in case of an
|
|
30
|
-
# assignment of 1000 partitions, we use around 4MB of space for tracking those metrics.
|
|
31
|
-
class Tracker
|
|
32
|
-
include Singleton
|
|
33
|
-
include Karafka::Core::Helpers::Time
|
|
34
|
-
|
|
35
|
-
# Empty hash we want to return in any case where we could not locate appropriate topic
|
|
36
|
-
# partition statistics.
|
|
37
|
-
EMPTY_HASH = {}.freeze
|
|
38
|
-
|
|
39
|
-
# Empty array to save on memory allocations.
|
|
40
|
-
EMPTY_ARRAY = [].freeze
|
|
41
|
-
|
|
42
|
-
# 5 minutes of cache. We cache last result per consumer group topic partition so we are
|
|
43
|
-
# not affected by involuntary rebalances during LRJ execution.
|
|
44
|
-
TTL = 5 * 60 * 1_000
|
|
45
|
-
|
|
46
|
-
private_constant :EMPTY_HASH, :EMPTY_ARRAY, :TTL
|
|
47
|
-
|
|
48
|
-
class << self
|
|
49
|
-
extend Forwardable
|
|
50
|
-
|
|
51
|
-
def_delegators :instance, :find, :add, :exists?, :clear
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Initializes the tracker with empty accumulator
|
|
55
|
-
def initialize
|
|
56
|
-
@accu = {}
|
|
57
|
-
@mutex = Mutex.new
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# Adds each partition statistics into internal accumulator. Single statistics set may
|
|
61
|
-
# contain data from multiple topics and their partitions because a single client can
|
|
62
|
-
# operate on multiple topics and partitions.
|
|
63
|
-
#
|
|
64
|
-
# We iterate over those topics and partitions and store topics partitions data only.
|
|
65
|
-
#
|
|
66
|
-
# @param consumer_group_id [String] id of the consumer group for which statistics were
|
|
67
|
-
# emitted.
|
|
68
|
-
# @param statistics [Hash] librdkafka enriched statistics
|
|
69
|
-
def add(consumer_group_id, statistics)
|
|
70
|
-
@mutex.synchronize do
|
|
71
|
-
statistics.fetch("topics", EMPTY_HASH).each do |topic_name, t_details|
|
|
72
|
-
t_details.fetch("partitions", EMPTY_HASH).each do |partition_id, p_details|
|
|
73
|
-
next unless track?(partition_id, p_details)
|
|
74
|
-
|
|
75
|
-
key = "#{consumer_group_id}_#{topic_name}_#{partition_id}"
|
|
76
|
-
@accu[key] = [monotonic_now, p_details]
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
evict
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Finds statistics about requested consumer group topic partition
|
|
85
|
-
#
|
|
86
|
-
# @param topic [Karafka::Routing::Topic]
|
|
87
|
-
# @param partition [Integer]
|
|
88
|
-
# @return [Hash] hash with given topic partition statistics or empty hash if not present
|
|
89
|
-
#
|
|
90
|
-
# @note We do not enclose it with a mutex mainly because the only thing that could happen
|
|
91
|
-
# here that would be a race-condition is a miss that anyhow we need to support due to
|
|
92
|
-
# how librdkafka ships metrics and a potential removal of data on heavily revoked LRJ.
|
|
93
|
-
def find(topic, partition)
|
|
94
|
-
key = "#{topic.consumer_group.id}_#{topic.name}_#{partition}"
|
|
95
|
-
@accu.fetch(key, EMPTY_ARRAY).last || EMPTY_HASH
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# Clears the tracker
|
|
99
|
-
def clear
|
|
100
|
-
@mutex.synchronize { @accu.clear }
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
private
|
|
104
|
-
|
|
105
|
-
# Evicts expired data from the cache
|
|
106
|
-
def evict
|
|
107
|
-
@accu.delete_if { |_, details| monotonic_now - details.first > TTL }
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Should we track given partition
|
|
111
|
-
#
|
|
112
|
-
# We do not track stopped partitions and the once we do not work with actively
|
|
113
|
-
# @param partition_id [String] partition id as a string
|
|
114
|
-
# @param p_details [Hash] partition statistics details
|
|
115
|
-
# @return [Boolean] true if we should track given partition
|
|
116
|
-
def track?(partition_id, p_details)
|
|
117
|
-
return false if partition_id == "-1"
|
|
118
|
-
|
|
119
|
-
fetch_state = p_details.fetch("fetch_state")
|
|
120
|
-
|
|
121
|
-
return false if fetch_state == "stopped"
|
|
122
|
-
return false if fetch_state == "none"
|
|
123
|
-
|
|
124
|
-
true
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
end
|
|
129
|
-
end
|