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
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
# Coordinators builder used to build coordinators per topic partition
|
|
9
|
+
#
|
|
10
|
+
# It provides direct pauses access for revocation
|
|
11
|
+
#
|
|
12
|
+
# @note This buffer operates only from the listener loop, thus we do not have to make it
|
|
13
|
+
# thread-safe.
|
|
14
|
+
class CoordinatorsBuffer
|
|
15
|
+
include Helpers::ConfigImporter.new(
|
|
16
|
+
coordinator_class: %i[internal processing consumer_groups coordinator_class]
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# @param topics [Karafka::Routing::Topics]
|
|
20
|
+
def initialize(topics)
|
|
21
|
+
@pauses_manager = Connection::PausesManager.new
|
|
22
|
+
@coordinators = Hash.new { |h, k| h[k] = {} }
|
|
23
|
+
@topics = topics
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param topic_name [String] topic name
|
|
27
|
+
# @param partition [Integer] partition number
|
|
28
|
+
# @return [Karafka::Processing::ConsumerGroups::Coordinator] found or created coordinator
|
|
29
|
+
def find_or_create(topic_name, partition)
|
|
30
|
+
@coordinators[topic_name][partition] ||= begin
|
|
31
|
+
routing_topic = @topics.find(topic_name)
|
|
32
|
+
|
|
33
|
+
coordinator_class.new(
|
|
34
|
+
routing_topic,
|
|
35
|
+
partition,
|
|
36
|
+
@pauses_manager.fetch(routing_topic, partition)
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Resumes processing of partitions for which pause time has ended.
|
|
42
|
+
# @yieldparam [String] topic name
|
|
43
|
+
# @yieldparam [Integer] partition number
|
|
44
|
+
def resume(&)
|
|
45
|
+
@pauses_manager.resume(&)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @param topic_name [String] topic name
|
|
49
|
+
# @param partition [Integer] partition number
|
|
50
|
+
def revoke(topic_name, partition)
|
|
51
|
+
return unless @coordinators[topic_name].key?(partition)
|
|
52
|
+
|
|
53
|
+
# The fact that we delete here does not change the fact that the executor still holds the
|
|
54
|
+
# reference to this coordinator. We delete it here, as we will no longer process any
|
|
55
|
+
# new stuff with it and we may need a new coordinator if we regain this partition, but the
|
|
56
|
+
# coordinator may still be in use
|
|
57
|
+
@coordinators[topic_name].delete(partition).revoke
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Clears coordinators and re-created the pauses manager
|
|
61
|
+
# This should be used only for critical errors recovery
|
|
62
|
+
def reset
|
|
63
|
+
@pauses_manager = Connection::PausesManager.new
|
|
64
|
+
@coordinators.clear
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
# Namespace that encapsulates all the logic related to processing data.
|
|
5
|
+
module Processing
|
|
6
|
+
# Consumer-group-specific processing components (driven by rebalance callbacks and partition
|
|
7
|
+
# ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
|
|
8
|
+
module ConsumerGroups
|
|
9
|
+
# Executors:
|
|
10
|
+
# - run consumers code (for `#call`) or run given preparation / teardown operations when needed
|
|
11
|
+
# from separate threads.
|
|
12
|
+
# - they re-create consumer instances in case of partitions that were revoked and assigned
|
|
13
|
+
# back.
|
|
14
|
+
#
|
|
15
|
+
# @note Executors are not removed after partition is revoked. They are not that big and will
|
|
16
|
+
# be re-used in case of a re-claim
|
|
17
|
+
#
|
|
18
|
+
# @note Since given consumer can run various operations, executor manages that and its
|
|
19
|
+
# lifecycle. There are following types of operations with appropriate before/after, etc:
|
|
20
|
+
#
|
|
21
|
+
# - consume - primary operation related to running user consumption code
|
|
22
|
+
# - idle - cleanup job that runs on idle runs where no messages would be passed to the end
|
|
23
|
+
# user. This is used for complex flows with filters, etc
|
|
24
|
+
# - revoked - runs after the partition was revoked
|
|
25
|
+
# - shutdown - runs when process is going to shutdown
|
|
26
|
+
class Executor
|
|
27
|
+
extend Forwardable
|
|
28
|
+
include Helpers::ConfigImporter.new(
|
|
29
|
+
strategy_selector: %i[internal processing consumer_groups strategy_selector],
|
|
30
|
+
expansions_selector: %i[internal processing consumer_groups expansions_selector]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
def_delegators :@coordinator, :topic, :partition
|
|
34
|
+
|
|
35
|
+
# @return [String] unique id that we use to ensure, that we use for state tracking
|
|
36
|
+
attr_reader :id
|
|
37
|
+
|
|
38
|
+
# @return [String] subscription group id to which a given executor belongs
|
|
39
|
+
attr_reader :group_id
|
|
40
|
+
|
|
41
|
+
# @return [Karafka::Messages::Messages] messages batch
|
|
42
|
+
attr_reader :messages
|
|
43
|
+
|
|
44
|
+
# @return [Karafka::Processing::ConsumerGroups::Coordinator] coordinator for this executor
|
|
45
|
+
attr_reader :coordinator
|
|
46
|
+
|
|
47
|
+
# @param group_id [String] id of the subscription group to which the executor belongs
|
|
48
|
+
# @param client [Karafka::Connection::Client] kafka client
|
|
49
|
+
# @param coordinator [Karafka::Processing::ConsumerGroups::Coordinator]
|
|
50
|
+
def initialize(group_id, client, coordinator)
|
|
51
|
+
@id = SecureRandom.hex(6)
|
|
52
|
+
@group_id = group_id
|
|
53
|
+
@client = client
|
|
54
|
+
@coordinator = coordinator
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Allows us to prepare the consumer in the listener thread prior to the job being send to
|
|
58
|
+
# be scheduled. It also allows to run some code that is time sensitive and cannot wait in the
|
|
59
|
+
# queue as it could cause starvation.
|
|
60
|
+
#
|
|
61
|
+
# @param messages [Array<Karafka::Messages::Message>]
|
|
62
|
+
def before_schedule_consume(messages)
|
|
63
|
+
# Recreate consumer with each batch if persistence is not enabled
|
|
64
|
+
# We reload the consumers with each batch instead of relying on some external signals
|
|
65
|
+
# when needed for consistency. That way devs may have it on or off and not in this
|
|
66
|
+
# middle state, where re-creation of a consumer instance would occur only sometimes
|
|
67
|
+
@consumer = nil unless topic.consumer_persistence
|
|
68
|
+
|
|
69
|
+
# First we build messages batch...
|
|
70
|
+
consumer.messages = Messages::Builders::Messages.call(
|
|
71
|
+
messages,
|
|
72
|
+
topic,
|
|
73
|
+
partition,
|
|
74
|
+
# the moment we've received the batch or actually the moment we've enqueued it,
|
|
75
|
+
# but good enough
|
|
76
|
+
Time.now
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
consumer.on_before_schedule_consume
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Runs setup and warm-up code in the worker prior to running the consumption
|
|
83
|
+
def before_consume
|
|
84
|
+
consumer.on_before_consume
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Runs the wrap/around execution context appropriate for a given action
|
|
88
|
+
# @param action [Symbol] action execution wrapped with our block
|
|
89
|
+
def wrap(action, &)
|
|
90
|
+
consumer.on_wrap(action, &)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Runs consumer data processing against given batch and handles failures and errors.
|
|
94
|
+
def consume
|
|
95
|
+
# We run the consumer client logic...
|
|
96
|
+
consumer.on_consume
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Runs consumer after consumption code
|
|
100
|
+
def after_consume
|
|
101
|
+
consumer.on_after_consume
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Runs the code needed before idle work is scheduled
|
|
105
|
+
def before_schedule_idle
|
|
106
|
+
consumer.on_before_schedule_idle
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Runs consumer idle operations
|
|
110
|
+
# This may include house-keeping or other state management changes that can occur but that
|
|
111
|
+
# not mean there are any new messages available for the end user to process
|
|
112
|
+
def idle
|
|
113
|
+
consumer.on_idle
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Runs the code needed before eofed work is scheduled
|
|
117
|
+
def before_schedule_eofed
|
|
118
|
+
consumer.on_before_schedule_eofed
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Runs consumed eofed operation.
|
|
122
|
+
# This may run even when there were no messages received prior. This will however not
|
|
123
|
+
# run when eof is received together with messages as in such case `#consume` will run
|
|
124
|
+
def eofed
|
|
125
|
+
consumer.on_eofed
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Runs code needed before revoked job is scheduled
|
|
129
|
+
def before_schedule_revoked
|
|
130
|
+
consumer.on_before_schedule_revoked if @consumer
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Runs the controller `#revoked` method that should be triggered when a given consumer is
|
|
134
|
+
# no longer needed due to partitions reassignment.
|
|
135
|
+
#
|
|
136
|
+
# @note Clearing the consumer will ensure, that if we get the partition back, it will be
|
|
137
|
+
# handled with a consumer with a clean state.
|
|
138
|
+
#
|
|
139
|
+
# @note We run it only when consumer was present, because presence indicates, that at least
|
|
140
|
+
# a single message has been consumed.
|
|
141
|
+
#
|
|
142
|
+
# @note We do not reset the consumer but we indicate need for recreation instead, because
|
|
143
|
+
# after the revocation, there still may be `#after_consume` running that needs a given
|
|
144
|
+
# consumer instance.
|
|
145
|
+
def revoked
|
|
146
|
+
consumer.on_revoked if @consumer
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Runs code needed before shutdown job is scheduled
|
|
150
|
+
def before_schedule_shutdown
|
|
151
|
+
consumer.on_before_schedule_shutdown if @consumer
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Runs the controller `#shutdown` method that should be triggered when a given consumer is
|
|
155
|
+
# no longer needed as we're closing the process.
|
|
156
|
+
#
|
|
157
|
+
# @note While we do not need to clear the consumer here, it's a good habit to clean after
|
|
158
|
+
# work is done.
|
|
159
|
+
def shutdown
|
|
160
|
+
# There is a case, where the consumer no longer exists because it was revoked, in case like
|
|
161
|
+
# that we do not build a new instance and shutdown should not be triggered.
|
|
162
|
+
consumer.on_shutdown if @consumer
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
private
|
|
166
|
+
|
|
167
|
+
# @return [Object] cached consumer instance
|
|
168
|
+
def consumer
|
|
169
|
+
@consumer ||= begin
|
|
170
|
+
topic = @coordinator.topic
|
|
171
|
+
|
|
172
|
+
strategy = strategy_selector.find(topic)
|
|
173
|
+
|
|
174
|
+
consumer = topic.consumer_class.new
|
|
175
|
+
# We use singleton class as the same consumer class may be used to process different
|
|
176
|
+
# topics with different settings
|
|
177
|
+
consumer.singleton_class.include(strategy)
|
|
178
|
+
|
|
179
|
+
# Specific features may expand consumer API beyond the injected strategy. The difference
|
|
180
|
+
# here is that strategy impacts the flow of states while extra APIs just provide some
|
|
181
|
+
# extra methods with informations, etc but do no deviate the flow behavior
|
|
182
|
+
expansions = expansions_selector.find(topic)
|
|
183
|
+
expansions.each { |expansion| consumer.singleton_class.include(expansion) }
|
|
184
|
+
|
|
185
|
+
consumer.client = @client
|
|
186
|
+
consumer.coordinator = @coordinator
|
|
187
|
+
# We assign producer only when not available already. It may already be available if
|
|
188
|
+
# user redefined the `#producer` method for example. This can be useful for example when
|
|
189
|
+
# having a multi-cluster setup and using a totally custom producer
|
|
190
|
+
consumer.producer ||= Karafka::App.producer
|
|
191
|
+
# Since we have some message-less flows (idle, etc), we initialize consumer with empty
|
|
192
|
+
# messages set. In production we have persistent consumers, so this is not a performance
|
|
193
|
+
# overhead as this will happen only once per consumer lifetime
|
|
194
|
+
consumer.messages = empty_messages
|
|
195
|
+
|
|
196
|
+
# Run the post-initialization hook for users that need to run some actions when consumer
|
|
197
|
+
# is built and ready (all basic state and info).
|
|
198
|
+
# Users should **not** overwrite the `#initialize` because it won't have all the needed
|
|
199
|
+
# data assigned yet.
|
|
200
|
+
consumer.on_initialized
|
|
201
|
+
|
|
202
|
+
consumer
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Initializes the messages set in case given operation would happen before any processing
|
|
207
|
+
# This prevents us from having no messages object at all as the messages object and
|
|
208
|
+
# its metadata may be used for statistics
|
|
209
|
+
def empty_messages
|
|
210
|
+
Messages::Builders::Messages.call(
|
|
211
|
+
[],
|
|
212
|
+
topic,
|
|
213
|
+
partition,
|
|
214
|
+
Time.now
|
|
215
|
+
)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
# Buffer for executors of a given subscription group. It wraps around the concept of building
|
|
9
|
+
# and caching them, so we can re-use them instead of creating new each time.
|
|
10
|
+
class ExecutorsBuffer
|
|
11
|
+
include Helpers::ConfigImporter.new(
|
|
12
|
+
executor_class: %i[internal processing consumer_groups executor_class]
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
# @param client [Connection::Client]
|
|
16
|
+
# @param subscription_group [Routing::SubscriptionGroup]
|
|
17
|
+
# @return [ExecutorsBuffer]
|
|
18
|
+
def initialize(client, subscription_group)
|
|
19
|
+
@subscription_group = subscription_group
|
|
20
|
+
@client = client
|
|
21
|
+
# We need two layers here to keep track of topics, partitions and processing groups
|
|
22
|
+
@buffer = Hash.new { |h, k| h[k] = Hash.new { |h2, k2| h2[k2] = {} } }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Finds or creates an executor based on the provided details
|
|
26
|
+
#
|
|
27
|
+
# @param topic [String] topic name
|
|
28
|
+
# @param partition [Integer] partition number
|
|
29
|
+
# @param parallel_key [String] parallel group key
|
|
30
|
+
# @param coordinator [Karafka::Processing::ConsumerGroups::Coordinator]
|
|
31
|
+
# @return [Executor, Pro::Processing::ConsumerGroups::Executor] consumer executor
|
|
32
|
+
def find_or_create(topic, partition, parallel_key, coordinator)
|
|
33
|
+
@buffer[topic][partition][parallel_key] ||= executor_class.new(
|
|
34
|
+
@subscription_group.id,
|
|
35
|
+
@client,
|
|
36
|
+
coordinator
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Finds all existing executors for given topic partition or creates one for it
|
|
41
|
+
# @param topic [String] topic name
|
|
42
|
+
# @param partition [Integer] partition number
|
|
43
|
+
# @param coordinator [Karafka::Processing::ConsumerGroups::Coordinator]
|
|
44
|
+
# @return [Array<Executor, Pro::Processing::ConsumerGroups::Executor>]
|
|
45
|
+
def find_all_or_create(topic, partition, coordinator)
|
|
46
|
+
existing = find_all(topic, partition)
|
|
47
|
+
|
|
48
|
+
return existing unless existing.empty?
|
|
49
|
+
|
|
50
|
+
[find_or_create(topic, partition, 0, coordinator)]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Revokes executors of a given topic partition, so they won't be used anymore for incoming
|
|
54
|
+
# messages
|
|
55
|
+
#
|
|
56
|
+
# @param topic [String] topic name
|
|
57
|
+
# @param partition [Integer] partition number
|
|
58
|
+
def revoke(topic, partition)
|
|
59
|
+
@buffer[topic][partition].clear
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Finds all the executors available for a given topic partition
|
|
63
|
+
#
|
|
64
|
+
# @param topic [String] topic name
|
|
65
|
+
# @param partition [Integer] partition number
|
|
66
|
+
# @return [Array<Executor, Pro::Processing::ConsumerGroups::Executor>] executors in use for this
|
|
67
|
+
# topic + partition
|
|
68
|
+
def find_all(topic, partition)
|
|
69
|
+
@buffer[topic][partition].values
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Iterates over all available executors and yields them together with topic and partition
|
|
73
|
+
# info
|
|
74
|
+
# @yieldparam [Routing::Topic] karafka routing topic object
|
|
75
|
+
# @yieldparam [Integer] partition number
|
|
76
|
+
# @yieldparam [Executor, Pro::Processing::ConsumerGroups::Executor] given executor
|
|
77
|
+
def each
|
|
78
|
+
@buffer.each_value do |partitions|
|
|
79
|
+
partitions.each_value do |executors|
|
|
80
|
+
executors.each_value do |executor|
|
|
81
|
+
yield(executor)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Clears the executors buffer. Useful for critical errors recovery.
|
|
88
|
+
def clear
|
|
89
|
+
@buffer.clear
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
# Selector of appropriate topic setup based features enhancements.
|
|
9
|
+
#
|
|
10
|
+
# Those expansions to the consumer API are NOT about the flow of processing. For this we have
|
|
11
|
+
# strategies. Those are suppose to provide certain extra APIs that user can use to get some
|
|
12
|
+
# extra non-flow related functionalities.
|
|
13
|
+
class ExpansionsSelector
|
|
14
|
+
# @param topic [Karafka::Routing::Topic] topic with settings based on which we find
|
|
15
|
+
# expansions
|
|
16
|
+
# @return [Array<Module>] modules with proper expansions we're suppose to use to enhance the
|
|
17
|
+
# consumer
|
|
18
|
+
def find(topic)
|
|
19
|
+
expansions = []
|
|
20
|
+
expansions << Processing::ConsumerGroups::InlineInsights::Consumer if topic.inline_insights?
|
|
21
|
+
expansions
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
# Namespace of the Inline Insights feature "non routing" related components
|
|
9
|
+
#
|
|
10
|
+
# @note We use both `#insights` because it is the feature name but also `#statistics` to make
|
|
11
|
+
# it consistent with the fact that we publish and operate on statistics. User can pick
|
|
12
|
+
# whichever name they prefer.
|
|
13
|
+
module InlineInsights
|
|
14
|
+
# Module that adds extra methods to the consumer that allow us to fetch the insights
|
|
15
|
+
module Consumer
|
|
16
|
+
# @return [Hash] empty hash or hash with given partition insights if already present
|
|
17
|
+
# @note We cache insights on the consumer, as in some scenarios we may no longer have them
|
|
18
|
+
# inside the Tracker, for example under involuntary revocation, incoming statistics may
|
|
19
|
+
# no longer have lost partition insights. Since we want to be consistent during single
|
|
20
|
+
# batch operations, we want to ensure, that if we have insights they are available
|
|
21
|
+
# throughout the whole processing.
|
|
22
|
+
def insights
|
|
23
|
+
insights = Tracker.find(topic, partition)
|
|
24
|
+
|
|
25
|
+
# If we no longer have new insights but we still have them locally, we can use them
|
|
26
|
+
return @insights if @insights && insights.empty?
|
|
27
|
+
# If insights are still the same, we can use them
|
|
28
|
+
return @insights if @insights.equal?(insights)
|
|
29
|
+
|
|
30
|
+
# If we've received new insights that are not empty, we can cache them
|
|
31
|
+
@insights = insights
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [Boolean] true if there are insights to work with, otherwise false
|
|
35
|
+
def insights?
|
|
36
|
+
!insights.empty?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
alias_method :statistics, :insights
|
|
40
|
+
alias_method :statistics?, :insights?
|
|
41
|
+
alias_method :inline_insights, :insights
|
|
42
|
+
alias_method :inline_insights?, :insights?
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
module InlineInsights
|
|
9
|
+
# Listener that adds statistics to our inline tracker
|
|
10
|
+
class Listener
|
|
11
|
+
# Adds statistics to the tracker
|
|
12
|
+
# @param event [Karafka::Core::Monitoring::Event] event with statistics
|
|
13
|
+
def on_statistics_emitted(event)
|
|
14
|
+
Tracker.add(
|
|
15
|
+
event[:group_id],
|
|
16
|
+
event[:statistics]
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
module InlineInsights
|
|
9
|
+
# Object used to track statistics coming from librdkafka in a way that can be accessible by
|
|
10
|
+
# the consumers
|
|
11
|
+
#
|
|
12
|
+
# We use a single tracker because we do not need state management here as our consumer groups
|
|
13
|
+
# clients identified by statistics name value are unique. On top of that, having a per
|
|
14
|
+
# process one that is a singleton allows us to use tracker easily also from other places like
|
|
15
|
+
# filtering API etc.
|
|
16
|
+
#
|
|
17
|
+
# @note We include cache of 5 minutes for revoked partitions to compensate for cases where
|
|
18
|
+
# when using LRJ a lost partition data would not be present anymore, however we would still
|
|
19
|
+
# be in the processing phase. Since those metrics are published with each `poll`, regular
|
|
20
|
+
# processing is not a subject of this issue. For LRJ we keep the reference. The only case
|
|
21
|
+
# where this could be switched midway is when LRJ is running for an extended period of time
|
|
22
|
+
# after the involuntary revocation. Having a time based cache instead of tracking
|
|
23
|
+
# simplifies the design as we do not have to deal with state tracking, especially since
|
|
24
|
+
# we would have to track also operations running in a revoked state.
|
|
25
|
+
#
|
|
26
|
+
# @note This tracker keeps in memory data about all topics and partitions that it encounters
|
|
27
|
+
# because in case of routing patterns, we may start getting statistics prior to registering
|
|
28
|
+
# given topic via dynamic routing expansions. In such case we would not have insights
|
|
29
|
+
# where they were actually available for us to use.
|
|
30
|
+
#
|
|
31
|
+
# @note Memory usage is negligible as long as we can evict expired data. Single metrics set
|
|
32
|
+
# for a single partition contains around 4KB of data. This means, that in case of an
|
|
33
|
+
# assignment of 1000 partitions, we use around 4MB of space for tracking those metrics.
|
|
34
|
+
class Tracker
|
|
35
|
+
include Singleton
|
|
36
|
+
include Karafka::Core::Helpers::Time
|
|
37
|
+
|
|
38
|
+
# Empty hash we want to return in any case where we could not locate appropriate topic
|
|
39
|
+
# partition statistics.
|
|
40
|
+
EMPTY_HASH = {}.freeze
|
|
41
|
+
|
|
42
|
+
# Empty array to save on memory allocations.
|
|
43
|
+
EMPTY_ARRAY = [].freeze
|
|
44
|
+
|
|
45
|
+
# 5 minutes of cache. We cache last result per consumer group topic partition so we are
|
|
46
|
+
# not affected by involuntary rebalances during LRJ execution.
|
|
47
|
+
TTL = 5 * 60 * 1_000
|
|
48
|
+
|
|
49
|
+
private_constant :EMPTY_HASH, :EMPTY_ARRAY, :TTL
|
|
50
|
+
|
|
51
|
+
class << self
|
|
52
|
+
extend Forwardable
|
|
53
|
+
|
|
54
|
+
def_delegators :instance, :find, :add, :exists?, :clear
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Initializes the tracker with empty accumulator
|
|
58
|
+
def initialize
|
|
59
|
+
@accu = {}
|
|
60
|
+
@mutex = Mutex.new
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Adds each partition statistics into internal accumulator. Single statistics set may
|
|
64
|
+
# contain data from multiple topics and their partitions because a single client can
|
|
65
|
+
# operate on multiple topics and partitions.
|
|
66
|
+
#
|
|
67
|
+
# We iterate over those topics and partitions and store topics partitions data only.
|
|
68
|
+
#
|
|
69
|
+
# @param group_id [String] id of the group for which statistics were emitted.
|
|
70
|
+
# @param statistics [Hash] librdkafka enriched statistics
|
|
71
|
+
def add(group_id, statistics)
|
|
72
|
+
@mutex.synchronize do
|
|
73
|
+
statistics.fetch("topics", EMPTY_HASH).each do |topic_name, t_details|
|
|
74
|
+
t_details.fetch("partitions", EMPTY_HASH).each do |partition_id, p_details|
|
|
75
|
+
next unless track?(partition_id, p_details)
|
|
76
|
+
|
|
77
|
+
key = "#{group_id}_#{topic_name}_#{partition_id}"
|
|
78
|
+
@accu[key] = [monotonic_now, p_details]
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
evict
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Finds statistics about requested consumer group topic partition
|
|
87
|
+
#
|
|
88
|
+
# @param topic [Karafka::Routing::Topic]
|
|
89
|
+
# @param partition [Integer]
|
|
90
|
+
# @return [Hash] hash with given topic partition statistics or empty hash if not present
|
|
91
|
+
#
|
|
92
|
+
# @note We do not enclose it with a mutex mainly because the only thing that could happen
|
|
93
|
+
# here that would be a race-condition is a miss that anyhow we need to support due to
|
|
94
|
+
# how librdkafka ships metrics and a potential removal of data on heavily revoked LRJ.
|
|
95
|
+
def find(topic, partition)
|
|
96
|
+
key = "#{topic.group.id}_#{topic.name}_#{partition}"
|
|
97
|
+
@accu.fetch(key, EMPTY_ARRAY).last || EMPTY_HASH
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Clears the tracker
|
|
101
|
+
def clear
|
|
102
|
+
@mutex.synchronize { @accu.clear }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
# Evicts expired data from the cache
|
|
108
|
+
def evict
|
|
109
|
+
@accu.delete_if { |_, details| monotonic_now - details.first > TTL }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Should we track given partition
|
|
113
|
+
#
|
|
114
|
+
# We do not track stopped partitions and the once we do not work with actively
|
|
115
|
+
# @param partition_id [String] partition id as a string
|
|
116
|
+
# @param p_details [Hash] partition statistics details
|
|
117
|
+
# @return [Boolean] true if we should track given partition
|
|
118
|
+
def track?(partition_id, p_details)
|
|
119
|
+
return false if partition_id == "-1"
|
|
120
|
+
|
|
121
|
+
fetch_state = p_details.fetch("fetch_state")
|
|
122
|
+
|
|
123
|
+
return false if fetch_state == "stopped"
|
|
124
|
+
return false if fetch_state == "none"
|
|
125
|
+
|
|
126
|
+
true
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
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
|
+
module ConsumerGroups
|
|
8
|
+
# Consumer-group-specific job types
|
|
9
|
+
module Jobs
|
|
10
|
+
# The main job type. It runs the executor that triggers given topic partition messages
|
|
11
|
+
# processing in an underlying consumer instance.
|
|
12
|
+
class Consume < ::Karafka::Processing::Jobs::Base
|
|
13
|
+
# @return [Array<Rdkafka::Consumer::Message>] array with messages
|
|
14
|
+
attr_reader :messages
|
|
15
|
+
|
|
16
|
+
self.action = :consume
|
|
17
|
+
|
|
18
|
+
# @param executor [Karafka::Processing::ConsumerGroups::Executor] executor that is suppose to run a given
|
|
19
|
+
# job
|
|
20
|
+
# @param messages [Karafka::Messages::Messages] karafka messages batch
|
|
21
|
+
# @return [Consume]
|
|
22
|
+
def initialize(executor, messages)
|
|
23
|
+
@executor = executor
|
|
24
|
+
@messages = messages
|
|
25
|
+
super()
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Runs all the preparation code on the executor that needs to happen before the job is
|
|
29
|
+
# scheduled.
|
|
30
|
+
def before_schedule
|
|
31
|
+
executor.before_schedule_consume(@messages)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Runs the before consumption preparations on the executor
|
|
35
|
+
def before_call
|
|
36
|
+
executor.before_consume
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Runs the given executor
|
|
40
|
+
def call
|
|
41
|
+
executor.consume
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Runs any error handling and other post-consumption stuff on the executor
|
|
45
|
+
def after_call
|
|
46
|
+
executor.after_consume
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|