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,48 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# Backwards-compatible alias kept for external code that references the old, un-namespaced
|
|
4
|
+
# constant. Will be removed in Karafka 3.0.
|
|
3
5
|
module Karafka
|
|
4
6
|
module Processing
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
attr_reader :strategies
|
|
8
|
-
|
|
9
|
-
# Features we support in the OSS offering.
|
|
10
|
-
SUPPORTED_FEATURES = %i[
|
|
11
|
-
active_job
|
|
12
|
-
manual_offset_management
|
|
13
|
-
dead_letter_queue
|
|
14
|
-
].freeze
|
|
15
|
-
|
|
16
|
-
# Initializes the strategy selector and preloads all strategies
|
|
17
|
-
def initialize
|
|
18
|
-
# We load them once for performance reasons not to do too many lookups
|
|
19
|
-
@strategies = find_all
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# @param topic [Karafka::Routing::Topic] topic with settings based on which we find strategy
|
|
23
|
-
# @return [Module] module with proper strategy
|
|
24
|
-
def find(topic)
|
|
25
|
-
feature_set = SUPPORTED_FEATURES.map do |feature_name|
|
|
26
|
-
topic.public_send("#{feature_name}?") ? feature_name : nil
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
feature_set.compact!
|
|
30
|
-
|
|
31
|
-
@strategies.find do |strategy|
|
|
32
|
-
strategy::FEATURES.sort == feature_set.sort
|
|
33
|
-
end || raise(Errors::StrategyNotFoundError, topic.name)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
private
|
|
37
|
-
|
|
38
|
-
# @return [Array<Module>] available strategies
|
|
39
|
-
def find_all
|
|
40
|
-
Strategies
|
|
41
|
-
.constants
|
|
42
|
-
.delete_if { |k| k == :Base }
|
|
43
|
-
.map { |k| Strategies.const_get(k) }
|
|
44
|
-
.uniq
|
|
45
|
-
end
|
|
46
|
-
end
|
|
7
|
+
# @see ConsumerGroups::StrategySelector
|
|
8
|
+
StrategySelector = ConsumerGroups::StrategySelector
|
|
47
9
|
end
|
|
48
10
|
end
|
|
@@ -27,17 +27,18 @@ module Karafka
|
|
|
27
27
|
attr_reader :id
|
|
28
28
|
|
|
29
29
|
# @param jobs_queue [JobsQueue]
|
|
30
|
+
# @param pool [WorkersPool] pool this worker belongs to (for deregistration on shutdown)
|
|
30
31
|
# @return [Worker]
|
|
31
|
-
def initialize(jobs_queue)
|
|
32
|
+
def initialize(jobs_queue, pool)
|
|
32
33
|
@id = SecureRandom.hex(6)
|
|
33
34
|
@jobs_queue = jobs_queue
|
|
35
|
+
@pool = pool
|
|
34
36
|
@non_wrapped_flow = worker_job_call_wrapper == false
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
private
|
|
38
40
|
|
|
39
|
-
# Runs processing of jobs in a loop
|
|
40
|
-
# Stops when queue is closed.
|
|
41
|
+
# Runs processing of jobs in a loop Stops when queue is closed.
|
|
41
42
|
def call
|
|
42
43
|
loop { break unless process }
|
|
43
44
|
end
|
|
@@ -80,6 +81,9 @@ module Karafka
|
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
else
|
|
84
|
+
# nil means either queue closed (full shutdown) or pool downscaling.
|
|
85
|
+
# Either way, deregister from pool so it reflects the actual worker count.
|
|
86
|
+
@pool.deregister(self)
|
|
83
87
|
false
|
|
84
88
|
end
|
|
85
89
|
# We signal critical exceptions, notify and do not allow worker to fail
|
|
@@ -95,7 +99,7 @@ module Karafka
|
|
|
95
99
|
type: "worker.process.error"
|
|
96
100
|
)
|
|
97
101
|
ensure
|
|
98
|
-
# job can be nil when the queue is being closed
|
|
102
|
+
# job can be nil when the queue is being closed or during pool downscaling
|
|
99
103
|
if job
|
|
100
104
|
@jobs_queue.complete(job)
|
|
101
105
|
job.finish!
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Processing
|
|
5
|
+
# Dynamic thread pool that manages worker threads.
|
|
6
|
+
# Supports scaling at runtime via {#scale}.
|
|
7
|
+
#
|
|
8
|
+
# All public methods that read or mutate `@workers` are synchronized via `@mutex`.
|
|
9
|
+
# `@size` is always updated under `@mutex` but can be read without locking for performance
|
|
10
|
+
# (integer assignment is atomic in MRI).
|
|
11
|
+
class WorkersPool
|
|
12
|
+
include Helpers::ConfigImporter.new(
|
|
13
|
+
concurrency: %i[concurrency],
|
|
14
|
+
worker_thread_priority: %i[worker_thread_priority],
|
|
15
|
+
monitor: %i[monitor]
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# @return [Integer] current number of workers registered in the pool.
|
|
19
|
+
# Reflects the actual thread count, not a target. After a downscale request this value
|
|
20
|
+
# converges towards the target as workers pick up nil sentinels and deregister.
|
|
21
|
+
# Updated atomically under mutex, safe to read without locking.
|
|
22
|
+
attr_reader :size
|
|
23
|
+
|
|
24
|
+
# Jobs queue reference, set by the Runner after both pool and queue are created.
|
|
25
|
+
# Must be assigned before calling {#scale}.
|
|
26
|
+
attr_writer :jobs_queue
|
|
27
|
+
|
|
28
|
+
# Initializes an empty pool with zero workers.
|
|
29
|
+
# Workers are not started until {#scale} is called, allowing the pool to be created early
|
|
30
|
+
# (e.g. in Server.run) before the jobs queue exists.
|
|
31
|
+
#
|
|
32
|
+
# @return [WorkersPool]
|
|
33
|
+
def initialize
|
|
34
|
+
@jobs_queue = nil
|
|
35
|
+
@workers = []
|
|
36
|
+
@size = 0
|
|
37
|
+
@mutex = Mutex.new
|
|
38
|
+
# Monotonically increasing index for naming worker threads. Indices are never reused
|
|
39
|
+
# after a worker exits, so thread names remain unique across the lifetime of the process
|
|
40
|
+
# and make it easy to correlate log entries with specific worker generations.
|
|
41
|
+
@next_index = 0
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Scale pool towards `target` workers (minimum 1).
|
|
45
|
+
#
|
|
46
|
+
# **Scaling up** is synchronous -- new worker threads are spawned and registered before this
|
|
47
|
+
# method returns. {#size} reflects the new count immediately.
|
|
48
|
+
#
|
|
49
|
+
# **Scaling down** is asynchronous -- nil sentinels are enqueued and workers exit when they
|
|
50
|
+
# pick one up. {#size} decreases gradually as workers deregister themselves. Callers that
|
|
51
|
+
# need to know when downsizing is complete should poll {#size} or listen for the
|
|
52
|
+
# `worker.scaling.down` instrumentation event (whose `:to` payload reports the *target*,
|
|
53
|
+
# not the current count).
|
|
54
|
+
#
|
|
55
|
+
# The entire read-decide-act cycle is synchronized to prevent stale reads.
|
|
56
|
+
# Instrumentation runs outside the mutex to avoid holding the lock during user callbacks.
|
|
57
|
+
#
|
|
58
|
+
# @param target [Integer] desired number of workers
|
|
59
|
+
def scale(target)
|
|
60
|
+
raise(Karafka::Errors::BaseError, "jobs_queue must be set before scaling") unless @jobs_queue
|
|
61
|
+
|
|
62
|
+
target = [target, 1].max
|
|
63
|
+
event = nil
|
|
64
|
+
|
|
65
|
+
@mutex.synchronize do
|
|
66
|
+
current = @workers.size
|
|
67
|
+
delta = target - current
|
|
68
|
+
|
|
69
|
+
if delta.positive?
|
|
70
|
+
event = grow(delta)
|
|
71
|
+
elsif delta.negative?
|
|
72
|
+
event = shrink(delta.abs)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
return unless event
|
|
77
|
+
|
|
78
|
+
monitor.instrument(*event)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @return [Boolean] true if all workers have stopped
|
|
82
|
+
def stopped?
|
|
83
|
+
snapshot.none?(&:alive?)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# @return [Array<Worker>] workers that are still alive
|
|
87
|
+
def alive
|
|
88
|
+
snapshot.select(&:alive?)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Forcefully terminate all worker threads.
|
|
92
|
+
def terminate
|
|
93
|
+
snapshot.each(&:terminate)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Wait for all current workers to finish.
|
|
97
|
+
def join
|
|
98
|
+
snapshot.each(&:join)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Called by a worker when it exits (queue closed or pool downscaling).
|
|
102
|
+
# Thread-safe -- worker threads call this from their own thread.
|
|
103
|
+
#
|
|
104
|
+
# @param worker [Worker] worker to remove from the pool
|
|
105
|
+
def deregister(worker)
|
|
106
|
+
@mutex.synchronize do
|
|
107
|
+
@workers.delete(worker)
|
|
108
|
+
@size = @workers.size
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
private
|
|
113
|
+
|
|
114
|
+
# @return [Array<Worker>] snapshot of workers taken under mutex
|
|
115
|
+
def snapshot
|
|
116
|
+
@mutex.synchronize { @workers.dup }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Add `count` workers and start their threads immediately.
|
|
120
|
+
# Must be called under `@mutex` (from {#scale}) or during construction (no contention).
|
|
121
|
+
#
|
|
122
|
+
# @param count [Integer] number of workers to add
|
|
123
|
+
# @return [Array] instrumentation event args to be emitted outside the mutex
|
|
124
|
+
def grow(count)
|
|
125
|
+
from = @workers.size
|
|
126
|
+
|
|
127
|
+
count.times do
|
|
128
|
+
worker = Worker.new(@jobs_queue, self)
|
|
129
|
+
@workers << worker
|
|
130
|
+
worker.async_call("karafka.worker##{@next_index}", worker_thread_priority)
|
|
131
|
+
@next_index += 1
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
@size = @workers.size
|
|
135
|
+
|
|
136
|
+
["worker.scaling.up", { workers_pool: self, from: from, to: @size }]
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Push nil into the queue to signal workers to exit.
|
|
140
|
+
# Whichever workers pick them up will deregister and stop.
|
|
141
|
+
# Must be called under `@mutex` (from {#scale}).
|
|
142
|
+
#
|
|
143
|
+
# @param count [Integer] number of workers to remove
|
|
144
|
+
# @return [Array, nil] instrumentation event args or nil if no-op
|
|
145
|
+
# @note Never shrinks below 1 worker.
|
|
146
|
+
def shrink(count)
|
|
147
|
+
effective = [count, @workers.size - 1].min
|
|
148
|
+
return if effective <= 0
|
|
149
|
+
|
|
150
|
+
from = @workers.size
|
|
151
|
+
effective.times { @jobs_queue << nil }
|
|
152
|
+
to = from - effective
|
|
153
|
+
|
|
154
|
+
["worker.scaling.down", { workers_pool: self, from: from, to: to }]
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
@@ -56,23 +56,23 @@ module Karafka
|
|
|
56
56
|
scope: %w[routes]
|
|
57
57
|
)
|
|
58
58
|
|
|
59
|
-
each do |
|
|
60
|
-
# Validate
|
|
59
|
+
each do |group|
|
|
60
|
+
# Validate group settings
|
|
61
61
|
Contracts::ConsumerGroup.new.validate!(
|
|
62
|
-
|
|
63
|
-
scope: ["routes",
|
|
62
|
+
group.to_h,
|
|
63
|
+
scope: ["routes", group.name]
|
|
64
64
|
)
|
|
65
65
|
|
|
66
66
|
# and then its topics settings
|
|
67
|
-
|
|
67
|
+
group.topics.each do |topic|
|
|
68
68
|
Contracts::Topic.new.validate!(
|
|
69
69
|
topic.to_h,
|
|
70
|
-
scope: ["routes",
|
|
70
|
+
scope: ["routes", group.name, topic.name]
|
|
71
71
|
)
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Initialize subscription groups after all the routing is done
|
|
75
|
-
|
|
75
|
+
group.subscription_groups
|
|
76
76
|
end
|
|
77
77
|
end
|
|
78
78
|
end
|
|
@@ -125,13 +125,13 @@ module Karafka
|
|
|
125
125
|
# Builds and saves given consumer group
|
|
126
126
|
# @param group_id [String, Symbol] name for consumer group
|
|
127
127
|
def consumer_group(group_id, &)
|
|
128
|
-
|
|
128
|
+
group = find { |existing| existing.name == group_id.to_s }
|
|
129
129
|
|
|
130
|
-
if
|
|
131
|
-
Proxy.new(
|
|
130
|
+
if group
|
|
131
|
+
Proxy.new(group, &).target
|
|
132
132
|
else
|
|
133
|
-
|
|
134
|
-
self << Proxy.new(
|
|
133
|
+
group = ConsumerGroup.new(group_id.to_s)
|
|
134
|
+
self << Proxy.new(group, &).target
|
|
135
135
|
end
|
|
136
136
|
end
|
|
137
137
|
|
|
@@ -26,11 +26,10 @@ module Karafka
|
|
|
26
26
|
# All topics including the DLQ topics names that are marked as active
|
|
27
27
|
topics = Set.new
|
|
28
28
|
|
|
29
|
-
data.each do |
|
|
30
|
-
|
|
29
|
+
data.each do |group|
|
|
30
|
+
group[:topics].each do |topic|
|
|
31
31
|
pat = topic[:patterns]
|
|
32
|
-
# Ignore pattern topics because they won't exist and should not be declarative
|
|
33
|
-
# managed
|
|
32
|
+
# Ignore pattern topics because they won't exist and should not be declarative managed
|
|
34
33
|
topics << topic[:name] if !pat || !pat[:active]
|
|
35
34
|
|
|
36
35
|
dlq = topic[:dead_letter_queue]
|
|
@@ -36,20 +36,20 @@ module Karafka
|
|
|
36
36
|
define_method :draw do |&block|
|
|
37
37
|
result = super(&block)
|
|
38
38
|
|
|
39
|
-
each do |
|
|
39
|
+
each do |group|
|
|
40
40
|
if scope::Contracts.const_defined?("ConsumerGroup", false)
|
|
41
41
|
scope::Contracts::ConsumerGroup.new.validate!(
|
|
42
|
-
|
|
43
|
-
scope: ["routes",
|
|
42
|
+
group.to_h,
|
|
43
|
+
scope: ["routes", group.name]
|
|
44
44
|
)
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
next unless scope::Contracts.const_defined?("Topic", false)
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
group.topics.each do |topic|
|
|
50
50
|
scope::Contracts::Topic.new.validate!(
|
|
51
51
|
topic.to_h,
|
|
52
|
-
scope: ["routes",
|
|
52
|
+
scope: ["routes", group.name, topic.name]
|
|
53
53
|
)
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class ActiveJob < Base
|
|
8
|
+
# Routing extensions for ActiveJob
|
|
9
|
+
module Builder
|
|
10
|
+
# This method simplifies routes definition for ActiveJob topics / queues by
|
|
11
|
+
# auto-injecting the consumer class
|
|
12
|
+
#
|
|
13
|
+
# @param name [String, Symbol] name of the topic where ActiveJob jobs should go
|
|
14
|
+
# @param block [Proc] block that we can use for some extra configuration
|
|
15
|
+
def active_job_topic(name, &block)
|
|
16
|
+
topic(name) do
|
|
17
|
+
consumer App.config.internal.active_job.consumer_class
|
|
18
|
+
active_job true
|
|
19
|
+
|
|
20
|
+
# This is handled by our custom ActiveJob consumer
|
|
21
|
+
# Without this, default behaviour would cause messages to skip upon shutdown as the
|
|
22
|
+
# offset would be committed for the last message
|
|
23
|
+
manual_offset_management true
|
|
24
|
+
|
|
25
|
+
next unless block
|
|
26
|
+
|
|
27
|
+
instance_eval(&block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class ActiveJob < Base
|
|
8
|
+
# Config for ActiveJob usage
|
|
9
|
+
Config = Struct.new(
|
|
10
|
+
:active,
|
|
11
|
+
keyword_init: true
|
|
12
|
+
) { alias_method :active?, :active }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class ActiveJob < Base
|
|
8
|
+
# This feature validation contracts
|
|
9
|
+
module Contracts
|
|
10
|
+
# Rules around using ActiveJob routing - basically you need to have ActiveJob available
|
|
11
|
+
# in order to be able to use active job routing
|
|
12
|
+
class Topic < Karafka::Contracts::Base
|
|
13
|
+
configure do |config|
|
|
14
|
+
config.error_messages = YAML.safe_load_file(
|
|
15
|
+
File.join(Karafka.gem_root, "config", "locales", "errors.yml")
|
|
16
|
+
).fetch("en").fetch("validations").fetch("routing").fetch("topic")
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
virtual do |data, errors|
|
|
20
|
+
next unless errors.empty?
|
|
21
|
+
next unless data[:active_job][:active]
|
|
22
|
+
# One should not define active job jobs without ActiveJob being available for usage
|
|
23
|
+
next if Object.const_defined?("ActiveJob::Base")
|
|
24
|
+
|
|
25
|
+
[[%i[consumer], :active_job_missing]]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# ActiveJob needs to always run with manual offset management
|
|
29
|
+
# Automatic offset management cannot work with ActiveJob. Otherwise we could mark as
|
|
30
|
+
# consumed jobs that did not run because of shutdown.
|
|
31
|
+
virtual do |data, errors|
|
|
32
|
+
next unless errors.empty?
|
|
33
|
+
next unless data[:active_job][:active]
|
|
34
|
+
next if data[:manual_offset_management][:active]
|
|
35
|
+
|
|
36
|
+
[[%i[manual_offset_management], :must_be_enabled]]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class ActiveJob < Base
|
|
8
|
+
# Routing proxy extensions for ActiveJob
|
|
9
|
+
module Proxy
|
|
10
|
+
include Builder
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class ActiveJob < Base
|
|
8
|
+
# Topic extensions to be able to check if given topic is ActiveJob topic
|
|
9
|
+
#
|
|
10
|
+
# @note ActiveJob topics do not have per-topic deserializer configuration. The deserializer
|
|
11
|
+
# is configured globally via `config.internal.active_job.deserializer` because Rails
|
|
12
|
+
# serializes jobs before dispatching them, requiring a consistent serialization format
|
|
13
|
+
# across all ActiveJob topics. If you need custom serialization (e.g., Avro, Protobuf),
|
|
14
|
+
# configure it once at the application level rather than per-topic.
|
|
15
|
+
module Topic
|
|
16
|
+
# This method sets up the extra instance variable to nil before calling
|
|
17
|
+
# the parent class initializer. The explicit initialization
|
|
18
|
+
# to nil is included as an optimization for Ruby's object shapes system,
|
|
19
|
+
# which improves memory layout and access performance.
|
|
20
|
+
def initialize(...)
|
|
21
|
+
@active_job = nil
|
|
22
|
+
super
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param active [Boolean] should this topic be considered one working with ActiveJob
|
|
26
|
+
#
|
|
27
|
+
# @note Since this feature supports only one setting (active), we can use the old API
|
|
28
|
+
# where the boolean would be an argument
|
|
29
|
+
def active_job(active = false)
|
|
30
|
+
@active_job ||= Config.new(active: active)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Boolean] is this an ActiveJob topic
|
|
34
|
+
def active_job?
|
|
35
|
+
active_job.active?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Hash] topic with all its native configuration options plus active job
|
|
39
|
+
# namespace settings
|
|
40
|
+
def to_h
|
|
41
|
+
super.merge(
|
|
42
|
+
active_job: active_job.to_h
|
|
43
|
+
).freeze
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
# Active-Job related components
|
|
8
|
+
# @note We can load it always, despite someone not using ActiveJob as it just adds a method
|
|
9
|
+
# to the routing, without actually breaking anything.
|
|
10
|
+
class ActiveJob < Base
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class DeadLetterQueue < Base
|
|
8
|
+
# Config for dead letter queue feature
|
|
9
|
+
Config = Struct.new(
|
|
10
|
+
:active,
|
|
11
|
+
# We add skip variants but in regular we support only `:one`
|
|
12
|
+
:max_retries,
|
|
13
|
+
# To what topic the skipped messages should be moved
|
|
14
|
+
:topic,
|
|
15
|
+
# Should retries be handled collectively on a batch or independently per message
|
|
16
|
+
:independent,
|
|
17
|
+
# Move to DLQ and mark as consumed in transactional mode (if applicable)
|
|
18
|
+
:transactional,
|
|
19
|
+
# Strategy to apply (if strategies supported)
|
|
20
|
+
:strategy,
|
|
21
|
+
# Should we use `#produce_sync` or `#produce_async`
|
|
22
|
+
:dispatch_method,
|
|
23
|
+
# Should we use `#mark_as_consumed` or `#mark_as_consumed!` (in flows that mark)
|
|
24
|
+
:marking_method,
|
|
25
|
+
# Should we mark as consumed after dispatch or not. True for most cases, except MOM where
|
|
26
|
+
# it is on user to decide (false by default)
|
|
27
|
+
:mark_after_dispatch,
|
|
28
|
+
# Initialize with kwargs
|
|
29
|
+
keyword_init: true
|
|
30
|
+
) do
|
|
31
|
+
alias_method :active?, :active
|
|
32
|
+
alias_method :independent?, :independent
|
|
33
|
+
alias_method :transactional?, :transactional
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Routing
|
|
5
|
+
module Features
|
|
6
|
+
module ConsumerGroups
|
|
7
|
+
class DeadLetterQueue < Base
|
|
8
|
+
# This feature validation contracts
|
|
9
|
+
module Contracts
|
|
10
|
+
# Rules around dead letter queue settings
|
|
11
|
+
class Topic < Karafka::Contracts::Base
|
|
12
|
+
configure do |config|
|
|
13
|
+
config.error_messages = YAML.safe_load_file(
|
|
14
|
+
File.join(Karafka.gem_root, "config", "locales", "errors.yml")
|
|
15
|
+
).fetch("en").fetch("validations").fetch("routing").fetch("topic")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
nested :dead_letter_queue do
|
|
19
|
+
required(:active) { |val| [true, false].include?(val) }
|
|
20
|
+
required(:independent) { |val| [true, false].include?(val) }
|
|
21
|
+
required(:max_retries) { |val| val.is_a?(Integer) && val >= 0 }
|
|
22
|
+
required(:transactional) { |val| [true, false].include?(val) }
|
|
23
|
+
required(:mark_after_dispatch) { |val| [true, false, nil].include?(val) }
|
|
24
|
+
|
|
25
|
+
required(:dispatch_method) do |val|
|
|
26
|
+
%i[produce_async produce_sync].include?(val)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
required(:marking_method) do |val|
|
|
30
|
+
%i[mark_as_consumed mark_as_consumed!].include?(val)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Validate topic name only if dlq is active
|
|
35
|
+
virtual do |data, errors|
|
|
36
|
+
next unless errors.empty?
|
|
37
|
+
|
|
38
|
+
dead_letter_queue = data[:dead_letter_queue]
|
|
39
|
+
|
|
40
|
+
next unless dead_letter_queue[:active]
|
|
41
|
+
|
|
42
|
+
topic = dead_letter_queue[:topic]
|
|
43
|
+
topic_regexp = Karafka::Contracts::TOPIC_REGEXP
|
|
44
|
+
|
|
45
|
+
# When topic is set to false, it means we just want to skip dispatch on DLQ
|
|
46
|
+
next if topic == false
|
|
47
|
+
next if topic.is_a?(String) && topic_regexp.match?(topic)
|
|
48
|
+
next if topic == :strategy
|
|
49
|
+
|
|
50
|
+
[[%i[dead_letter_queue topic], :format]]
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|