karafka 2.4.0 → 2.4.18
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
- checksums.yaml.gz.sig +0 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +26 -34
- data/.github/workflows/ci.yml +18 -6
- data/.ruby-version +1 -1
- data/CHANGELOG.md +146 -1
- data/Gemfile +10 -5
- data/Gemfile.lock +60 -39
- data/LICENSE +8 -3
- data/bin/integrations +13 -1
- data/certs/cert.pem +26 -0
- data/config/locales/errors.yml +18 -2
- data/config/locales/pro_errors.yml +44 -0
- data/docker-compose.yml +1 -3
- data/karafka.gemspec +6 -4
- data/lib/active_job/queue_adapters/karafka_adapter.rb +18 -7
- data/lib/karafka/active_job/dispatcher.rb +13 -0
- data/lib/karafka/active_job/job_extensions.rb +3 -0
- data/lib/karafka/admin.rb +86 -0
- data/lib/karafka/app.rb +17 -0
- data/lib/karafka/base_consumer.rb +130 -19
- data/lib/karafka/cli/base.rb +24 -8
- data/lib/karafka/cli/install.rb +2 -1
- data/lib/karafka/cli/server.rb +1 -0
- data/lib/karafka/cli/swarm.rb +1 -0
- data/lib/karafka/cli/topics/align.rb +12 -2
- data/lib/karafka/cli/topics/plan.rb +54 -6
- data/lib/karafka/cli/topics.rb +45 -18
- data/lib/karafka/connection/client.rb +102 -35
- data/lib/karafka/connection/listener.rb +48 -11
- data/lib/karafka/connection/messages_buffer.rb +19 -6
- data/lib/karafka/connection/proxy.rb +3 -0
- data/lib/karafka/connection/raw_messages_buffer.rb +43 -9
- data/lib/karafka/connection/rebalance_manager.rb +24 -13
- data/lib/karafka/contracts/config.rb +4 -0
- data/lib/karafka/contracts/consumer_group.rb +17 -0
- data/lib/karafka/contracts/routing.rb +59 -0
- data/lib/karafka/contracts/topic.rb +14 -0
- data/lib/karafka/embedded.rb +46 -3
- data/lib/karafka/errors.rb +3 -2
- data/lib/karafka/helpers/async.rb +11 -2
- data/lib/karafka/helpers/config_importer.rb +13 -0
- data/lib/karafka/instrumentation/assignments_tracker.rb +7 -2
- data/lib/karafka/instrumentation/logger_listener.rb +45 -4
- data/lib/karafka/instrumentation/notifications.rb +12 -0
- data/lib/karafka/instrumentation/vendors/appsignal/client.rb +32 -11
- data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +1 -1
- data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +3 -1
- data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +17 -19
- data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +27 -18
- data/lib/karafka/instrumentation/vendors/kubernetes/base_listener.rb +2 -2
- data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +41 -13
- data/lib/karafka/messages/message.rb +9 -9
- data/lib/karafka/pro/active_job/consumer.rb +2 -10
- data/lib/karafka/pro/active_job/dispatcher.rb +67 -19
- data/lib/karafka/pro/active_job/job_options_contract.rb +12 -10
- data/lib/karafka/pro/base_consumer.rb +2 -10
- data/lib/karafka/pro/cleaner/errors.rb +2 -10
- data/lib/karafka/pro/cleaner/messages/message.rb +14 -12
- data/lib/karafka/pro/cleaner/messages/messages.rb +2 -10
- data/lib/karafka/pro/cleaner/messages/metadata.rb +41 -0
- data/lib/karafka/pro/cleaner.rb +3 -10
- data/lib/karafka/pro/connection/manager.rb +6 -10
- data/lib/karafka/pro/connection/multiplexing/listener.rb +2 -10
- data/lib/karafka/pro/contracts/base.rb +2 -10
- data/lib/karafka/pro/contracts/server_cli_options.rb +2 -10
- data/lib/karafka/pro/encryption/cipher.rb +2 -10
- data/lib/karafka/pro/encryption/contracts/config.rb +2 -10
- data/lib/karafka/pro/encryption/errors.rb +2 -10
- data/lib/karafka/pro/encryption/messages/middleware.rb +2 -10
- data/lib/karafka/pro/encryption/messages/parser.rb +2 -10
- data/lib/karafka/pro/encryption/setup/config.rb +2 -10
- data/lib/karafka/pro/encryption.rb +2 -10
- data/lib/karafka/pro/instrumentation/performance_tracker.rb +2 -10
- data/lib/karafka/pro/iterator/expander.rb +2 -10
- data/lib/karafka/pro/iterator/tpl_builder.rb +2 -10
- data/lib/karafka/pro/iterator.rb +2 -10
- data/lib/karafka/pro/loader.rb +5 -11
- data/lib/karafka/pro/processing/adaptive_iterator/consumer.rb +54 -0
- data/lib/karafka/pro/processing/adaptive_iterator/tracker.rb +67 -0
- data/lib/karafka/pro/processing/collapser.rb +2 -10
- data/lib/karafka/pro/processing/coordinator.rb +2 -10
- data/lib/karafka/pro/processing/coordinators/errors_tracker.rb +2 -10
- data/lib/karafka/pro/processing/coordinators/filters_applier.rb +19 -10
- data/lib/karafka/pro/processing/coordinators/virtual_offset_manager.rb +2 -10
- data/lib/karafka/pro/processing/executor.rb +2 -10
- data/lib/karafka/pro/processing/expansions_selector.rb +3 -10
- data/lib/karafka/pro/processing/filters/base.rb +14 -10
- data/lib/karafka/pro/processing/filters/delayer.rb +4 -12
- data/lib/karafka/pro/processing/filters/expirer.rb +2 -10
- data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +2 -10
- data/lib/karafka/pro/processing/filters/throttler.rb +2 -10
- data/lib/karafka/pro/processing/filters/virtual_limiter.rb +2 -10
- data/lib/karafka/pro/processing/jobs/consume_non_blocking.rb +4 -10
- data/lib/karafka/pro/processing/jobs/eofed_non_blocking.rb +26 -0
- data/lib/karafka/pro/processing/jobs/periodic.rb +4 -10
- data/lib/karafka/pro/processing/jobs/periodic_non_blocking.rb +4 -10
- data/lib/karafka/pro/processing/jobs/revoked_non_blocking.rb +4 -10
- data/lib/karafka/pro/processing/jobs_builder.rb +14 -10
- data/lib/karafka/pro/processing/jobs_queue.rb +2 -10
- data/lib/karafka/pro/processing/offset_metadata/consumer.rb +2 -10
- data/lib/karafka/pro/processing/offset_metadata/fetcher.rb +2 -10
- data/lib/karafka/pro/processing/offset_metadata/listener.rb +2 -10
- data/lib/karafka/pro/processing/partitioner.rb +35 -24
- data/lib/karafka/pro/processing/periodic_job/consumer.rb +2 -10
- data/lib/karafka/pro/processing/piping/consumer.rb +2 -10
- data/lib/karafka/pro/processing/schedulers/base.rb +2 -10
- data/lib/karafka/pro/processing/schedulers/default.rb +3 -10
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom.rb +3 -11
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +3 -11
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +3 -11
- data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +3 -11
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +3 -11
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/ftr_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +5 -13
- data/lib/karafka/pro/processing/strategies/aj/mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/aj/mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/base.rb +2 -10
- data/lib/karafka/pro/processing/strategies/default.rb +140 -58
- data/lib/karafka/pro/processing/strategies/dlq/default.rb +23 -15
- data/lib/karafka/pro/processing/strategies/dlq/ftr.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +3 -11
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +7 -11
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +19 -11
- data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/lrj.rb +3 -11
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +19 -11
- data/lib/karafka/pro/processing/strategies/dlq/lrj_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/mom.rb +24 -16
- data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/dlq/vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/ftr/default.rb +17 -12
- data/lib/karafka/pro/processing/strategies/ftr/vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/lrj/default.rb +5 -13
- data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +3 -11
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +2 -10
- data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/lrj/mom.rb +4 -12
- data/lib/karafka/pro/processing/strategies/lrj/mom_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/lrj/vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/mom/default.rb +2 -10
- data/lib/karafka/pro/processing/strategies/mom/ftr.rb +2 -10
- data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/mom/vp.rb +2 -10
- data/lib/karafka/pro/processing/strategies/vp/default.rb +5 -10
- data/lib/karafka/pro/processing/strategies.rb +2 -10
- data/lib/karafka/pro/processing/strategy_selector.rb +2 -10
- data/lib/karafka/pro/processing/subscription_groups_coordinator.rb +2 -10
- data/lib/karafka/pro/recurring_tasks/consumer.rb +97 -0
- data/lib/karafka/pro/recurring_tasks/contracts/config.rb +45 -0
- data/lib/karafka/pro/recurring_tasks/contracts/task.rb +33 -0
- data/lib/karafka/pro/recurring_tasks/deserializer.rb +27 -0
- data/lib/karafka/pro/recurring_tasks/dispatcher.rb +79 -0
- data/lib/karafka/pro/recurring_tasks/errors.rb +26 -0
- data/lib/karafka/pro/recurring_tasks/executor.rb +144 -0
- data/lib/karafka/pro/recurring_tasks/listener.rb +30 -0
- data/lib/karafka/pro/recurring_tasks/matcher.rb +30 -0
- data/lib/karafka/pro/recurring_tasks/schedule.rb +55 -0
- data/lib/karafka/pro/recurring_tasks/serializer.rb +105 -0
- data/lib/karafka/pro/recurring_tasks/setup/config.rb +44 -0
- data/lib/karafka/pro/recurring_tasks/task.rb +143 -0
- data/lib/karafka/pro/recurring_tasks.rb +79 -0
- data/lib/karafka/pro/routing/features/active_job/builder.rb +2 -10
- data/lib/karafka/pro/routing/features/active_job.rb +2 -10
- data/lib/karafka/pro/routing/features/adaptive_iterator/config.rb +26 -0
- data/lib/karafka/pro/routing/features/adaptive_iterator/contracts/topic.rb +66 -0
- data/lib/karafka/pro/routing/features/adaptive_iterator/topic.rb +54 -0
- data/lib/karafka/pro/routing/features/adaptive_iterator.rb +23 -0
- data/lib/karafka/pro/routing/features/base.rb +2 -10
- data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/dead_letter_queue.rb +2 -10
- data/lib/karafka/pro/routing/features/delaying/config.rb +2 -10
- data/lib/karafka/pro/routing/features/delaying/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/delaying/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/delaying.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments/config.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments/contracts/consumer_group.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments/subscription_group.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/direct_assignments.rb +2 -10
- data/lib/karafka/pro/routing/features/expiring/config.rb +2 -10
- data/lib/karafka/pro/routing/features/expiring/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/expiring/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/expiring.rb +2 -10
- data/lib/karafka/pro/routing/features/filtering/config.rb +2 -10
- data/lib/karafka/pro/routing/features/filtering/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/filtering/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/filtering.rb +2 -10
- data/lib/karafka/pro/routing/features/inline_insights/config.rb +2 -10
- data/lib/karafka/pro/routing/features/inline_insights/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/inline_insights/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/inline_insights.rb +2 -10
- data/lib/karafka/pro/routing/features/long_running_job/config.rb +2 -10
- data/lib/karafka/pro/routing/features/long_running_job/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/long_running_job/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/long_running_job.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/config.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/patches/contracts/consumer_group.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/subscription_group.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing/subscription_groups_builder.rb +2 -10
- data/lib/karafka/pro/routing/features/multiplexing.rb +2 -10
- data/lib/karafka/pro/routing/features/non_blocking_job/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/non_blocking_job.rb +2 -10
- data/lib/karafka/pro/routing/features/offset_metadata/config.rb +2 -10
- data/lib/karafka/pro/routing/features/offset_metadata/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/offset_metadata.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/builder.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/config.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/consumer_group.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/contracts/consumer_group.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/contracts/pattern.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/detector.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/pattern.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/patterns.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns/topics.rb +2 -10
- data/lib/karafka/pro/routing/features/patterns.rb +2 -10
- data/lib/karafka/pro/routing/features/pausing/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/pausing/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/pausing.rb +2 -10
- data/lib/karafka/pro/routing/features/periodic_job/config.rb +2 -10
- data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/periodic_job/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/periodic_job.rb +2 -10
- data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +123 -0
- data/lib/karafka/pro/routing/features/recurring_tasks/config.rb +20 -0
- data/lib/karafka/pro/routing/features/recurring_tasks/contracts/topic.rb +32 -0
- data/lib/karafka/pro/routing/features/recurring_tasks/proxy.rb +19 -0
- data/lib/karafka/pro/routing/features/recurring_tasks/topic.rb +36 -0
- data/lib/karafka/pro/routing/features/recurring_tasks.rb +17 -0
- data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +123 -0
- data/lib/karafka/pro/routing/features/scheduled_messages/config.rb +20 -0
- data/lib/karafka/pro/routing/features/scheduled_messages/contracts/topic.rb +32 -0
- data/lib/karafka/pro/routing/features/scheduled_messages/proxy.rb +19 -0
- data/lib/karafka/pro/routing/features/scheduled_messages/topic.rb +36 -0
- data/lib/karafka/pro/routing/features/scheduled_messages.rb +16 -0
- data/lib/karafka/pro/routing/features/swarm/config.rb +2 -10
- data/lib/karafka/pro/routing/features/swarm/contracts/routing.rb +2 -10
- data/lib/karafka/pro/routing/features/swarm/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/swarm/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/swarm.rb +2 -10
- data/lib/karafka/pro/routing/features/throttling/config.rb +2 -10
- data/lib/karafka/pro/routing/features/throttling/contracts/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/throttling/topic.rb +2 -10
- data/lib/karafka/pro/routing/features/throttling.rb +2 -10
- data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +3 -10
- data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +3 -10
- data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +10 -12
- data/lib/karafka/pro/routing/features/virtual_partitions.rb +2 -10
- data/lib/karafka/pro/scheduled_messages/consumer.rb +177 -0
- data/lib/karafka/pro/scheduled_messages/contracts/config.rb +48 -0
- data/lib/karafka/pro/scheduled_messages/contracts/message.rb +88 -0
- data/lib/karafka/pro/scheduled_messages/daily_buffer.rb +71 -0
- data/lib/karafka/pro/scheduled_messages/day.rb +37 -0
- data/lib/karafka/pro/scheduled_messages/deserializers/headers.rb +38 -0
- data/lib/karafka/pro/scheduled_messages/deserializers/payload.rb +27 -0
- data/lib/karafka/pro/scheduled_messages/dispatcher.rb +114 -0
- data/lib/karafka/pro/scheduled_messages/errors.rb +20 -0
- data/lib/karafka/pro/scheduled_messages/max_epoch.rb +33 -0
- data/lib/karafka/pro/scheduled_messages/proxy.rb +177 -0
- data/lib/karafka/pro/scheduled_messages/schema_validator.rb +29 -0
- data/lib/karafka/pro/scheduled_messages/serializer.rb +47 -0
- data/lib/karafka/pro/scheduled_messages/setup/config.rb +52 -0
- data/lib/karafka/pro/scheduled_messages/state.rb +54 -0
- data/lib/karafka/pro/scheduled_messages/tracker.rb +56 -0
- data/lib/karafka/pro/scheduled_messages.rb +59 -0
- data/lib/karafka/pro/swarm/liveness_listener.rb +2 -10
- data/lib/karafka/processing/coordinator.rb +14 -0
- data/lib/karafka/processing/executor.rb +29 -1
- data/lib/karafka/processing/jobs/base.rb +13 -0
- data/lib/karafka/processing/jobs/consume.rb +2 -0
- data/lib/karafka/processing/jobs/eofed.rb +29 -0
- data/lib/karafka/processing/jobs/idle.rb +2 -0
- data/lib/karafka/processing/jobs/revoked.rb +2 -0
- data/lib/karafka/processing/jobs/shutdown.rb +2 -0
- data/lib/karafka/processing/jobs_builder.rb +6 -0
- data/lib/karafka/processing/schedulers/default.rb +1 -0
- data/lib/karafka/processing/strategies/aj_dlq_mom.rb +1 -1
- data/lib/karafka/processing/strategies/default.rb +45 -13
- data/lib/karafka/processing/strategies/dlq.rb +19 -5
- data/lib/karafka/processing/strategies/dlq_mom.rb +27 -8
- data/lib/karafka/processing/worker.rb +26 -13
- data/lib/karafka/railtie.rb +11 -42
- data/lib/karafka/routing/builder.rb +19 -1
- data/lib/karafka/routing/consumer_group.rb +9 -14
- data/lib/karafka/routing/features/dead_letter_queue/config.rb +3 -0
- data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +1 -0
- data/lib/karafka/routing/features/dead_letter_queue/topic.rb +7 -2
- data/lib/karafka/routing/features/eofed/config.rb +15 -0
- data/lib/karafka/routing/features/eofed/contracts/topic.rb +39 -0
- data/lib/karafka/routing/features/eofed/topic.rb +31 -0
- data/lib/karafka/routing/features/eofed.rb +14 -0
- data/lib/karafka/routing/subscription_group.rb +29 -1
- data/lib/karafka/routing/topic.rb +24 -1
- data/lib/karafka/runner.rb +10 -9
- data/lib/karafka/server.rb +37 -1
- data/lib/karafka/setup/attributes_map.rb +11 -4
- data/lib/karafka/setup/config.rb +11 -52
- data/lib/karafka/setup/defaults_injector.rb +64 -0
- data/lib/karafka/swarm/node.rb +2 -0
- data/lib/karafka/swarm/supervisor.rb +11 -2
- data/lib/karafka/templates/karafka.rb.erb +2 -2
- data/lib/karafka/version.rb +1 -1
- data/lib/karafka.rb +47 -7
- data.tar.gz.sig +0 -0
- metadata +116 -33
- metadata.gz.sig +0 -0
- data/certs/cert_chain.pem +0 -26
|
@@ -16,8 +16,11 @@ module Karafka
|
|
|
16
16
|
RETRYABLE_DEFAULT_ERRORS = %i[
|
|
17
17
|
all_brokers_down
|
|
18
18
|
timed_out
|
|
19
|
+
transport
|
|
20
|
+
network_exception
|
|
19
21
|
not_coordinator
|
|
20
22
|
not_leader_for_partition
|
|
23
|
+
coordinator_load_in_progress
|
|
21
24
|
].freeze
|
|
22
25
|
|
|
23
26
|
private_constant :RETRYABLE_DEFAULT_ERRORS
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Connection
|
|
5
|
-
# Buffer for raw librdkafka messages.
|
|
5
|
+
# Buffer for raw librdkafka messages and eof status.
|
|
6
6
|
#
|
|
7
7
|
# When message is added to this buffer, it gets assigned to an array with other messages from
|
|
8
8
|
# the same topic and partition.
|
|
@@ -12,14 +12,24 @@ module Karafka
|
|
|
12
12
|
# @note We store data here in groups per topic partition to handle the revocation case, where
|
|
13
13
|
# we may need to remove messages from a single topic partition.
|
|
14
14
|
class RawMessagesBuffer
|
|
15
|
+
include Karafka::Core::Helpers::Time
|
|
16
|
+
|
|
15
17
|
attr_reader :size
|
|
16
18
|
|
|
19
|
+
# @return [Float] last polling time in milliseconds (monotonic)
|
|
20
|
+
attr_reader :last_polled_at
|
|
21
|
+
|
|
17
22
|
# @return [Karafka::Connection::MessagesBuffer] buffer instance
|
|
18
23
|
def initialize
|
|
19
24
|
@size = 0
|
|
25
|
+
@last_polled_at = monotonic_now
|
|
26
|
+
|
|
20
27
|
@groups = Hash.new do |topic_groups, topic|
|
|
21
28
|
topic_groups[topic] = Hash.new do |partition_groups, partition|
|
|
22
|
-
partition_groups[partition] =
|
|
29
|
+
partition_groups[partition] = {
|
|
30
|
+
eof: false,
|
|
31
|
+
messages: []
|
|
32
|
+
}
|
|
23
33
|
end
|
|
24
34
|
end
|
|
25
35
|
end
|
|
@@ -30,7 +40,21 @@ module Karafka
|
|
|
30
40
|
# @return [Array<Rdkafka::Consumer::Message>] given partition topic sub-buffer array
|
|
31
41
|
def <<(message)
|
|
32
42
|
@size += 1
|
|
33
|
-
@groups[message.topic][message.partition]
|
|
43
|
+
partition_state = @groups[message.topic][message.partition]
|
|
44
|
+
partition_state[:messages] << message
|
|
45
|
+
partition_state[:eof] = false
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Marks given topic partition as one that reached eof
|
|
49
|
+
# @param topic [String] topic that reached eof
|
|
50
|
+
# @param partition [Integer] partition that reached eof
|
|
51
|
+
def eof(topic, partition)
|
|
52
|
+
@groups[topic][partition][:eof] = true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Marks the last polling time that can be accessed via `#last_polled_at`
|
|
56
|
+
def polled
|
|
57
|
+
@last_polled_at = monotonic_now
|
|
34
58
|
end
|
|
35
59
|
|
|
36
60
|
# Allows to iterate over all the topics and partitions messages
|
|
@@ -38,10 +62,11 @@ module Karafka
|
|
|
38
62
|
# @yieldparam [String] topic name
|
|
39
63
|
# @yieldparam [Integer] partition number
|
|
40
64
|
# @yieldparam [Array<Rdkafka::Consumer::Message>] topic partition aggregated results
|
|
65
|
+
# @yieldparam [Boolean] has polling of this partition reach eof
|
|
41
66
|
def each
|
|
42
67
|
@groups.each do |topic, partitions|
|
|
43
|
-
partitions.each do |partition,
|
|
44
|
-
yield(topic, partition, messages)
|
|
68
|
+
partitions.each do |partition, details|
|
|
69
|
+
yield(topic, partition, details[:messages], details[:eof])
|
|
45
70
|
end
|
|
46
71
|
end
|
|
47
72
|
end
|
|
@@ -69,8 +94,8 @@ module Karafka
|
|
|
69
94
|
# again and we do want to ensure as few duplications as possible
|
|
70
95
|
def uniq!
|
|
71
96
|
@groups.each_value do |partitions|
|
|
72
|
-
partitions.each_value do |
|
|
73
|
-
messages.uniq!(&:offset)
|
|
97
|
+
partitions.each_value do |details|
|
|
98
|
+
details[:messages].uniq!(&:offset)
|
|
74
99
|
end
|
|
75
100
|
end
|
|
76
101
|
|
|
@@ -83,6 +108,11 @@ module Karafka
|
|
|
83
108
|
# we save ourselves some objects allocations. We cannot clear the underlying arrays as they
|
|
84
109
|
# may be used in other threads for data processing, thus if we would clear it, we could
|
|
85
110
|
# potentially clear a raw messages array for a job that is in the jobs queue.
|
|
111
|
+
#
|
|
112
|
+
# @note We do not clear the eof assignments because they can span across batch pollings.
|
|
113
|
+
# Since eof is not raised non-stop and is silenced after an eof poll, if we would clean it
|
|
114
|
+
# here we would loose the notion of it. The reset state for it should happen when we do
|
|
115
|
+
# discover new messages for given topic partition.
|
|
86
116
|
def clear
|
|
87
117
|
@size = 0
|
|
88
118
|
@groups.each_value(&:clear)
|
|
@@ -92,8 +122,12 @@ module Karafka
|
|
|
92
122
|
|
|
93
123
|
# Updates the messages count if we performed any operations that could change the state
|
|
94
124
|
def recount!
|
|
95
|
-
@size =
|
|
96
|
-
|
|
125
|
+
@size = 0
|
|
126
|
+
|
|
127
|
+
@groups.each_value do |partitions|
|
|
128
|
+
partitions.each_value do |details|
|
|
129
|
+
@size += details[:messages].size
|
|
130
|
+
end
|
|
97
131
|
end
|
|
98
132
|
end
|
|
99
133
|
end
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
module Connection
|
|
5
|
-
# Manager for tracking changes in the partitions assignment after the assignment is done
|
|
5
|
+
# Manager for tracking changes in the partitions assignment after the assignment is done and
|
|
6
|
+
# for ensuring, that proper buffer related operations that may be impacted by the rebalance
|
|
7
|
+
# state are applied.
|
|
6
8
|
#
|
|
7
9
|
# We need tracking of those to clean up consumers that will no longer process given partitions
|
|
8
10
|
# as they were taken away.
|
|
@@ -30,13 +32,15 @@ module Karafka
|
|
|
30
32
|
private_constant :EMPTY_ARRAY
|
|
31
33
|
|
|
32
34
|
# @param subscription_group_id [String] subscription group id
|
|
35
|
+
# @param buffer [Karafka::Connection::RawMessagesBuffer]
|
|
33
36
|
# @return [RebalanceManager]
|
|
34
|
-
def initialize(subscription_group_id)
|
|
37
|
+
def initialize(subscription_group_id, buffer)
|
|
35
38
|
@assigned_partitions = {}
|
|
36
39
|
@revoked_partitions = {}
|
|
37
40
|
@changed = false
|
|
38
41
|
@active = false
|
|
39
42
|
@subscription_group_id = subscription_group_id
|
|
43
|
+
@buffer = buffer
|
|
40
44
|
|
|
41
45
|
# Connects itself to the instrumentation pipeline so rebalances can be tracked
|
|
42
46
|
::Karafka.monitor.subscribe(self)
|
|
@@ -64,17 +68,6 @@ module Karafka
|
|
|
64
68
|
@active
|
|
65
69
|
end
|
|
66
70
|
|
|
67
|
-
# We consider as lost only partitions that were taken away and not re-assigned back to us
|
|
68
|
-
def lost_partitions
|
|
69
|
-
lost_partitions = {}
|
|
70
|
-
|
|
71
|
-
revoked_partitions.each do |topic, partitions|
|
|
72
|
-
lost_partitions[topic] = partitions - assigned_partitions.fetch(topic, EMPTY_ARRAY)
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
lost_partitions
|
|
76
|
-
end
|
|
77
|
-
|
|
78
71
|
# Callback that kicks in inside of rdkafka, when new partitions were assigned.
|
|
79
72
|
#
|
|
80
73
|
# @private
|
|
@@ -99,6 +92,24 @@ module Karafka
|
|
|
99
92
|
@active = true
|
|
100
93
|
@revoked_partitions = event[:tpl].to_h.transform_values { |part| part.map(&:partition) }
|
|
101
94
|
@changed = true
|
|
95
|
+
|
|
96
|
+
remove_revoked_and_duplicated_messages
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
# We may have a case where in the middle of data polling, we've lost a partition.
|
|
102
|
+
# In a case like this we should remove all the pre-buffered messages from list partitions as
|
|
103
|
+
# we are no longer responsible in a given process for processing those messages and they
|
|
104
|
+
# should have been picked up by a different process.
|
|
105
|
+
def remove_revoked_and_duplicated_messages
|
|
106
|
+
@revoked_partitions.each do |topic, partitions|
|
|
107
|
+
partitions.each do |partition|
|
|
108
|
+
@buffer.delete(topic, partition)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
@buffer.uniq!
|
|
102
113
|
end
|
|
103
114
|
end
|
|
104
115
|
end
|
|
@@ -34,6 +34,7 @@ module Karafka
|
|
|
34
34
|
required(:max_wait_time) { |val| val.is_a?(Integer) && val.positive? }
|
|
35
35
|
required(:group_id) { |val| val.is_a?(String) && Contracts::TOPIC_REGEXP.match?(val) }
|
|
36
36
|
required(:kafka) { |val| val.is_a?(Hash) && !val.empty? }
|
|
37
|
+
required(:strict_declarative_topics) { |val| [true, false].include?(val) }
|
|
37
38
|
|
|
38
39
|
nested(:swarm) do
|
|
39
40
|
required(:nodes) { |val| val.is_a?(Integer) && val.positive? }
|
|
@@ -79,6 +80,7 @@ module Karafka
|
|
|
79
80
|
nested(:connection) do
|
|
80
81
|
required(:manager) { |val| !val.nil? }
|
|
81
82
|
required(:conductor) { |val| !val.nil? }
|
|
83
|
+
required(:reset_backoff) { |val| val.is_a?(Integer) && val >= 1_000 }
|
|
82
84
|
|
|
83
85
|
nested(:proxy) do
|
|
84
86
|
nested(:commit) do
|
|
@@ -115,6 +117,8 @@ module Karafka
|
|
|
115
117
|
required(:partitioner_class) { |val| !val.nil? }
|
|
116
118
|
required(:strategy_selector) { |val| !val.nil? }
|
|
117
119
|
required(:expansions_selector) { |val| !val.nil? }
|
|
120
|
+
required(:executor_class) { |val| !val.nil? }
|
|
121
|
+
required(:worker_job_call_wrapper) { |val| val == false || val.respond_to?(:wrap) }
|
|
118
122
|
end
|
|
119
123
|
|
|
120
124
|
nested(:active_job) do
|
|
@@ -25,6 +25,23 @@ module Karafka
|
|
|
25
25
|
[[%i[topics], :names_not_unique]]
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# Prevent same topics subscriptions in one CG with different consumer classes
|
|
29
|
+
# This should prevent users from accidentally creating multi-sg one CG setup with weird
|
|
30
|
+
# different consumer usage. If you need to consume same topic twice, use distinct CGs.
|
|
31
|
+
virtual do |data, errors|
|
|
32
|
+
next unless errors.empty?
|
|
33
|
+
|
|
34
|
+
topics_consumers = Hash.new { |h, k| h[k] = Set.new }
|
|
35
|
+
|
|
36
|
+
data.fetch(:topics).map do |topic|
|
|
37
|
+
topics_consumers[topic[:name]] << topic[:consumer]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
next if topics_consumers.values.map(&:size).all? { |count| count == 1 }
|
|
41
|
+
|
|
42
|
+
[[%i[topics], :many_consumers_same_topic]]
|
|
43
|
+
end
|
|
44
|
+
|
|
28
45
|
virtual do |data, errors|
|
|
29
46
|
next unless errors.empty?
|
|
30
47
|
next unless ::Karafka::App.config.strict_topics_namespacing
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Karafka
|
|
4
|
+
module Contracts
|
|
5
|
+
# Ensures that routing wide rules are obeyed
|
|
6
|
+
class Routing < Base
|
|
7
|
+
configure do |config|
|
|
8
|
+
config.error_messages = YAML.safe_load(
|
|
9
|
+
File.read(
|
|
10
|
+
File.join(Karafka.gem_root, 'config', 'locales', 'errors.yml')
|
|
11
|
+
)
|
|
12
|
+
).fetch('en').fetch('validations').fetch('routing')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Ensures, that when declarative topics strict requirement is on, all topics have
|
|
16
|
+
# declarative definition (including DLQ topics)
|
|
17
|
+
# @note It will ignore routing pattern topics because those topics are virtual
|
|
18
|
+
virtual do |data, errors|
|
|
19
|
+
next unless errors.empty?
|
|
20
|
+
# Do not validate declaratives unless required and explicitly enabled
|
|
21
|
+
next unless Karafka::App.config.strict_declarative_topics
|
|
22
|
+
|
|
23
|
+
# Collects declarative topics. Please note, that any topic that has a `#topic` reference,
|
|
24
|
+
# will be declarative by default unless explicitly disabled. This however does not apply
|
|
25
|
+
# to the DLQ definitions
|
|
26
|
+
dec_topics = Set.new
|
|
27
|
+
# All topics including the DLQ topics names that are marked as active
|
|
28
|
+
topics = Set.new
|
|
29
|
+
|
|
30
|
+
data.each do |consumer_group|
|
|
31
|
+
consumer_group[:topics].each do |topic|
|
|
32
|
+
pat = topic[:patterns]
|
|
33
|
+
# Ignore pattern topics because they won't exist and should not be declarative
|
|
34
|
+
# managed
|
|
35
|
+
topics << topic[:name] if !pat || !pat[:active]
|
|
36
|
+
|
|
37
|
+
dlq = topic[:dead_letter_queue]
|
|
38
|
+
topics << dlq[:topic] if dlq[:active]
|
|
39
|
+
|
|
40
|
+
dec = topic[:declaratives]
|
|
41
|
+
|
|
42
|
+
dec_topics << topic[:name] if dec[:active]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
missing_dec = topics - dec_topics
|
|
47
|
+
|
|
48
|
+
next if missing_dec.empty?
|
|
49
|
+
|
|
50
|
+
missing_dec.map do |topic_name|
|
|
51
|
+
[
|
|
52
|
+
[:topics, topic_name],
|
|
53
|
+
:without_declarative_definition
|
|
54
|
+
]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -51,6 +51,20 @@ module Karafka
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
+
# When users redefine kafka scope settings per topic, they often forget to define the
|
|
55
|
+
# basic stuff as they assume it is auto-inherited. It is not (unless inherit flag used),
|
|
56
|
+
# leaving them with things like bootstrap.servers undefined. This checks that bootstrap
|
|
57
|
+
# servers are defined so we can catch those issues before they cause more problems.
|
|
58
|
+
virtual do |data, errors|
|
|
59
|
+
next unless errors.empty?
|
|
60
|
+
|
|
61
|
+
kafka = data.fetch(:kafka)
|
|
62
|
+
|
|
63
|
+
next if kafka.key?(:'bootstrap.servers')
|
|
64
|
+
|
|
65
|
+
[[%w[kafka bootstrap.servers], :missing]]
|
|
66
|
+
end
|
|
67
|
+
|
|
54
68
|
virtual do |data, errors|
|
|
55
69
|
next unless errors.empty?
|
|
56
70
|
next unless ::Karafka::App.config.strict_topics_namespacing
|
data/lib/karafka/embedded.rb
CHANGED
|
@@ -2,15 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
module Karafka
|
|
4
4
|
# Allows to start and stop Karafka as part of a different process
|
|
5
|
+
# Following limitations and restrictions apply:
|
|
6
|
+
#
|
|
7
|
+
# - `#start` cannot be called from a trap context - non blocking
|
|
8
|
+
# - `#quiet` - can be called from a trap context - non blocking
|
|
9
|
+
# - `#stop` - can be called from a trap context - blocking
|
|
5
10
|
module Embedded
|
|
6
11
|
class << self
|
|
12
|
+
# Lock for ensuring we do not control embedding in parallel
|
|
13
|
+
MUTEX = Mutex.new
|
|
14
|
+
|
|
15
|
+
private_constant :MUTEX
|
|
16
|
+
|
|
7
17
|
# Starts Karafka without supervision and without ownership of signals in a background thread
|
|
8
18
|
# so it won't interrupt other things running
|
|
9
19
|
def start
|
|
20
|
+
MUTEX.synchronize do
|
|
21
|
+
# Prevent from double-starting
|
|
22
|
+
return if @started
|
|
23
|
+
|
|
24
|
+
@started = true
|
|
25
|
+
end
|
|
26
|
+
|
|
10
27
|
Thread.new do
|
|
11
28
|
Thread.current.name = 'karafka.embedded'
|
|
12
29
|
|
|
13
|
-
Karafka::Process.tags.add(:execution_mode, 'embedded')
|
|
30
|
+
Karafka::Process.tags.add(:execution_mode, 'mode:embedded')
|
|
31
|
+
Karafka::Server.execution_mode = :embedded
|
|
14
32
|
Karafka::Server.start
|
|
15
33
|
end
|
|
16
34
|
end
|
|
@@ -19,9 +37,32 @@ module Karafka
|
|
|
19
37
|
#
|
|
20
38
|
# @note This method is blocking because we want to wait until Karafka is stopped with final
|
|
21
39
|
# process shutdown
|
|
40
|
+
#
|
|
41
|
+
# @note This method **is** safe to run from a trap context.
|
|
22
42
|
def stop
|
|
23
|
-
#
|
|
24
|
-
|
|
43
|
+
# Prevent from double stopping
|
|
44
|
+
unless @stopping
|
|
45
|
+
Thread.new do
|
|
46
|
+
Thread.current.name = 'karafka.embedded.stopping'
|
|
47
|
+
|
|
48
|
+
stop = false
|
|
49
|
+
|
|
50
|
+
# We spawn a new thread because `#stop` may be called from a trap context
|
|
51
|
+
MUTEX.synchronize do
|
|
52
|
+
break if @stopping
|
|
53
|
+
|
|
54
|
+
@stopping = true
|
|
55
|
+
stop = true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
next unless stop
|
|
59
|
+
|
|
60
|
+
Karafka::Server.stop
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Since we want to have this blocking, we wait for the background thread
|
|
65
|
+
sleep(0.1) until Karafka::App.terminated?
|
|
25
66
|
end
|
|
26
67
|
|
|
27
68
|
# Quiets Karafka upon any event
|
|
@@ -29,6 +70,8 @@ module Karafka
|
|
|
29
70
|
# @note This method is not blocking and will not wait for Karafka to fully quiet.
|
|
30
71
|
# It will trigger the quiet procedure but won't wait.
|
|
31
72
|
#
|
|
73
|
+
# @note This method **can** be called from a trap context.
|
|
74
|
+
#
|
|
32
75
|
# @note Please keep in mind you need to `#stop` to actually stop the server anyhow.
|
|
33
76
|
def quiet
|
|
34
77
|
Karafka::Server.quiet
|
data/lib/karafka/errors.rb
CHANGED
|
@@ -82,10 +82,11 @@ module Karafka
|
|
|
82
82
|
AssignmentLostError = Class.new(BaseError)
|
|
83
83
|
|
|
84
84
|
# Raised if optional dependencies like karafka-web are required in a version that is not
|
|
85
|
-
# supported by the current framework version.
|
|
85
|
+
# supported by the current framework version or when an optional dependency is missing.
|
|
86
86
|
#
|
|
87
87
|
# Because we do not want to require web out of the box and we do not want to lock web with
|
|
88
|
-
# karafka 1:1, we do such a sanity check
|
|
88
|
+
# karafka 1:1, we do such a sanity check. This also applies to cases where some external
|
|
89
|
+
# optional dependencies are needed but not available.
|
|
89
90
|
DependencyConstraintsError = Class.new(BaseError)
|
|
90
91
|
|
|
91
92
|
# Raised when we were not able to open pidfd for given pid
|
|
@@ -22,13 +22,22 @@ module Karafka
|
|
|
22
22
|
def included(base)
|
|
23
23
|
base.extend ::Forwardable
|
|
24
24
|
|
|
25
|
-
base.def_delegators :@thread, :join, :terminate, :
|
|
25
|
+
base.def_delegators :@thread, :join, :terminate, :name
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [Boolean] true if thread is present and is running, false otherwise
|
|
30
|
+
def alive?
|
|
31
|
+
MUTEX.synchronize do
|
|
32
|
+
return false unless @thread
|
|
33
|
+
|
|
34
|
+
@thread.alive?
|
|
26
35
|
end
|
|
27
36
|
end
|
|
28
37
|
|
|
29
38
|
# Runs the `#call` method in a new thread
|
|
30
39
|
# @param thread_name [String] name that we want to assign to the thread when we start it
|
|
31
|
-
def async_call(thread_name
|
|
40
|
+
def async_call(thread_name)
|
|
32
41
|
MUTEX.synchronize do
|
|
33
42
|
return if @thread&.alive?
|
|
34
43
|
|
|
@@ -25,6 +25,19 @@ module Karafka
|
|
|
25
25
|
RUBY
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
+
|
|
29
|
+
# @param model [Object] object to which we want to add the config fetcher on a class level
|
|
30
|
+
def extended(model)
|
|
31
|
+
super
|
|
32
|
+
|
|
33
|
+
@attributes.each do |name, path|
|
|
34
|
+
model.class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
35
|
+
def self.#{name}
|
|
36
|
+
@#{name} ||= ::Karafka::App.config.#{path.join('.')}
|
|
37
|
+
end
|
|
38
|
+
RUBY
|
|
39
|
+
end
|
|
40
|
+
end
|
|
28
41
|
end
|
|
29
42
|
end
|
|
30
43
|
end
|
|
@@ -31,8 +31,13 @@ module Karafka
|
|
|
31
31
|
def current
|
|
32
32
|
assignments = {}
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
# Since the `@assignments` state can change during a rebalance, if we would iterate over
|
|
35
|
+
# it exactly during state change, we would end up with the following error:
|
|
36
|
+
# RuntimeError: can't add a new key into hash during iteration
|
|
37
|
+
@mutex.synchronize do
|
|
38
|
+
@assignments.each do |topic, partitions|
|
|
39
|
+
assignments[topic] = partitions.dup.freeze
|
|
40
|
+
end
|
|
36
41
|
end
|
|
37
42
|
|
|
38
43
|
assignments.freeze
|
|
@@ -41,7 +41,7 @@ module Karafka
|
|
|
41
41
|
return unless log_polling?
|
|
42
42
|
|
|
43
43
|
listener = event[:caller]
|
|
44
|
-
time = event[:time]
|
|
44
|
+
time = event[:time].round(2)
|
|
45
45
|
messages_count = event[:messages_buffer].size
|
|
46
46
|
|
|
47
47
|
message = "[#{listener.id}] Polled #{messages_count} messages in #{time}ms"
|
|
@@ -69,14 +69,14 @@ module Karafka
|
|
|
69
69
|
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
|
70
70
|
def on_worker_processed(event)
|
|
71
71
|
job = event[:job]
|
|
72
|
-
time = event[:time]
|
|
72
|
+
time = event[:time].round(2)
|
|
73
73
|
job_type = job.class.to_s.split('::').last
|
|
74
74
|
consumer = job.executor.topic.consumer
|
|
75
75
|
topic = job.executor.topic.name
|
|
76
76
|
partition = job.executor.partition
|
|
77
77
|
info <<~MSG.tr("\n", ' ').strip!
|
|
78
78
|
[#{job.id}] #{job_type} job for #{consumer}
|
|
79
|
-
on #{topic}/#{partition} finished in #{time}ms
|
|
79
|
+
on #{topic}/#{partition} finished in #{time} ms
|
|
80
80
|
MSG
|
|
81
81
|
end
|
|
82
82
|
|
|
@@ -127,6 +127,21 @@ module Karafka
|
|
|
127
127
|
MSG
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
+
# Prints info about seeking to a particular location
|
|
131
|
+
#
|
|
132
|
+
# @param event [Karafka::Core::Monitoring::Event] event details including payload
|
|
133
|
+
def on_consumer_consuming_seek(event)
|
|
134
|
+
topic = event[:topic]
|
|
135
|
+
partition = event[:partition]
|
|
136
|
+
seek_offset = event[:message].offset
|
|
137
|
+
consumer = event[:caller]
|
|
138
|
+
|
|
139
|
+
info <<~MSG.tr("\n", ' ').strip!
|
|
140
|
+
[#{consumer.id}] Seeking from #{consumer.class}
|
|
141
|
+
on topic #{topic}/#{partition} to offset #{seek_offset}
|
|
142
|
+
MSG
|
|
143
|
+
end
|
|
144
|
+
|
|
130
145
|
# Logs info about system signals that Karafka received and prints backtrace for threads in
|
|
131
146
|
# case of ttin
|
|
132
147
|
#
|
|
@@ -275,6 +290,12 @@ module Karafka
|
|
|
275
290
|
details = (error.backtrace || []).join("\n")
|
|
276
291
|
|
|
277
292
|
case type
|
|
293
|
+
when 'consumer.initialized.error'
|
|
294
|
+
error "Consumer initialized error: #{error}"
|
|
295
|
+
error details
|
|
296
|
+
when 'consumer.wrap.error'
|
|
297
|
+
error "Consumer wrap failed due to an error: #{error}"
|
|
298
|
+
error details
|
|
278
299
|
when 'consumer.consume.error'
|
|
279
300
|
error "Consumer consuming error: #{error}"
|
|
280
301
|
error details
|
|
@@ -290,6 +311,9 @@ module Karafka
|
|
|
290
311
|
when 'consumer.tick.error'
|
|
291
312
|
error "Consumer on tick failed due to an error: #{error}"
|
|
292
313
|
error details
|
|
314
|
+
when 'consumer.eofed.error'
|
|
315
|
+
error "Consumer on eofed failed due to an error: #{error}"
|
|
316
|
+
error details
|
|
293
317
|
when 'consumer.after_consume.error'
|
|
294
318
|
error "Consumer on after_consume failed due to an error: #{error}"
|
|
295
319
|
error details
|
|
@@ -306,7 +330,24 @@ module Karafka
|
|
|
306
330
|
fatal "Runner crashed due to an error: #{error}"
|
|
307
331
|
fatal details
|
|
308
332
|
when 'app.stopping.error'
|
|
309
|
-
|
|
333
|
+
# Counts number of workers and listeners that were still active when forcing the
|
|
334
|
+
# shutdown. Please note, that unless all listeners are closed, workers will not finalize
|
|
335
|
+
# their operations as well.
|
|
336
|
+
# We need to check if listeners and workers are assigned as during super early stages of
|
|
337
|
+
# boot they are not.
|
|
338
|
+
listeners = Server.listeners ? Server.listeners.count(&:active?) : 0
|
|
339
|
+
workers = Server.workers ? Server.workers.count(&:alive?) : 0
|
|
340
|
+
|
|
341
|
+
message = <<~MSG.tr("\n", ' ').strip!
|
|
342
|
+
Forceful Karafka server stop with:
|
|
343
|
+
#{workers} active workers and
|
|
344
|
+
#{listeners} active listeners
|
|
345
|
+
MSG
|
|
346
|
+
|
|
347
|
+
error message
|
|
348
|
+
when 'app.forceful_stopping.error'
|
|
349
|
+
error "Forceful shutdown error occurred: #{error}"
|
|
350
|
+
error details
|
|
310
351
|
when 'librdkafka.error'
|
|
311
352
|
error "librdkafka internal error occurred: #{error}"
|
|
312
353
|
error details
|
|
@@ -48,11 +48,16 @@ module Karafka
|
|
|
48
48
|
connection.listener.stopping
|
|
49
49
|
connection.listener.stopped
|
|
50
50
|
|
|
51
|
+
consumer.initialize
|
|
52
|
+
consumer.initialized
|
|
53
|
+
|
|
51
54
|
consumer.before_schedule_consume
|
|
52
55
|
consumer.consume
|
|
53
56
|
consumer.consumed
|
|
54
57
|
consumer.consuming.pause
|
|
55
58
|
consumer.consuming.retry
|
|
59
|
+
consumer.consuming.seek
|
|
60
|
+
consumer.consuming.transaction
|
|
56
61
|
|
|
57
62
|
consumer.before_schedule_idle
|
|
58
63
|
consumer.idle
|
|
@@ -65,10 +70,17 @@ module Karafka
|
|
|
65
70
|
consumer.tick
|
|
66
71
|
consumer.ticked
|
|
67
72
|
|
|
73
|
+
consumer.before_schedule_eofed
|
|
74
|
+
consumer.eof
|
|
75
|
+
consumer.eofed
|
|
76
|
+
|
|
68
77
|
consumer.before_schedule_shutdown
|
|
69
78
|
consumer.shutting_down
|
|
70
79
|
consumer.shutdown
|
|
71
80
|
|
|
81
|
+
consumer.wrap
|
|
82
|
+
consumer.wrapped
|
|
83
|
+
|
|
72
84
|
dead_letter_queue.dispatched
|
|
73
85
|
|
|
74
86
|
filtering.throttled
|