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
|
@@ -23,11 +23,16 @@ module Karafka
|
|
|
23
23
|
# @param action_name [String] action name. For processing this should be equal to
|
|
24
24
|
# consumer class + method name
|
|
25
25
|
def start_transaction(action_name)
|
|
26
|
-
transaction =
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
transaction =
|
|
27
|
+
if version_4_or_newer?
|
|
28
|
+
::Appsignal::Transaction.create(namespace_name)
|
|
29
|
+
else
|
|
30
|
+
::Appsignal::Transaction.create(
|
|
31
|
+
SecureRandom.uuid,
|
|
32
|
+
namespace_name,
|
|
33
|
+
::Appsignal::Transaction::GenericRequest.new({})
|
|
34
|
+
)
|
|
35
|
+
end
|
|
31
36
|
|
|
32
37
|
transaction.set_action_if_nil(action_name)
|
|
33
38
|
end
|
|
@@ -45,10 +50,10 @@ module Karafka
|
|
|
45
50
|
def metadata=(metadata_hash)
|
|
46
51
|
return unless transaction?
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
current_transaction = transaction
|
|
49
54
|
|
|
50
55
|
stringify_hash(metadata_hash).each do |key, value|
|
|
51
|
-
|
|
56
|
+
current_transaction.set_metadata(key, value)
|
|
52
57
|
end
|
|
53
58
|
end
|
|
54
59
|
|
|
@@ -78,15 +83,20 @@ module Karafka
|
|
|
78
83
|
)
|
|
79
84
|
end
|
|
80
85
|
|
|
81
|
-
#
|
|
86
|
+
# Report the error that occurred to Appsignal
|
|
82
87
|
#
|
|
83
88
|
# @param error [Object] error we want to ship to Appsignal
|
|
84
|
-
def
|
|
89
|
+
def report_error(error)
|
|
90
|
+
if ::Appsignal.respond_to?(:report_error)
|
|
91
|
+
# This helper will always report the error
|
|
92
|
+
::Appsignal.report_error(error) do |transaction|
|
|
93
|
+
transaction.set_namespace(namespace_name)
|
|
94
|
+
end
|
|
85
95
|
# If we have an active transaction we should use it instead of creating a generic one
|
|
86
96
|
# That way proper namespace and other data may be transferred
|
|
87
97
|
#
|
|
88
98
|
# In case there is no transaction, a new generic background job one will be used
|
|
89
|
-
|
|
99
|
+
elsif transaction?
|
|
90
100
|
transaction.set_error(error)
|
|
91
101
|
else
|
|
92
102
|
::Appsignal.send_error(error) do |transaction|
|
|
@@ -99,7 +109,11 @@ module Karafka
|
|
|
99
109
|
# @param name [Symbol] probe name
|
|
100
110
|
# @param probe [Proc] code to run every minute
|
|
101
111
|
def register_probe(name, probe)
|
|
102
|
-
::Appsignal::
|
|
112
|
+
if ::Appsignal::Probes.respond_to?(:register)
|
|
113
|
+
::Appsignal::Probes.register(name, probe)
|
|
114
|
+
else
|
|
115
|
+
::Appsignal::Minutely.probes.register(name, probe)
|
|
116
|
+
end
|
|
103
117
|
end
|
|
104
118
|
|
|
105
119
|
private
|
|
@@ -129,6 +143,13 @@ module Karafka
|
|
|
129
143
|
def namespace_name
|
|
130
144
|
@namespace_name ||= ::Appsignal::Transaction::BACKGROUND_JOB
|
|
131
145
|
end
|
|
146
|
+
|
|
147
|
+
# @return [Boolean] is this v4+ version of Appsignal gem or older. Used for backwards
|
|
148
|
+
# compatibility checks.
|
|
149
|
+
def version_4_or_newer?
|
|
150
|
+
@version_4_or_newer ||=
|
|
151
|
+
Gem::Version.new(::Appsignal::VERSION) >= Gem::Version.new('4.0.0')
|
|
152
|
+
end
|
|
132
153
|
end
|
|
133
154
|
end
|
|
134
155
|
end
|
|
@@ -48,6 +48,7 @@ module Karafka
|
|
|
48
48
|
consumer.revoked.error
|
|
49
49
|
consumer.shutdown.error
|
|
50
50
|
consumer.tick.error
|
|
51
|
+
consumer.eofed.error
|
|
51
52
|
].freeze
|
|
52
53
|
|
|
53
54
|
private_constant :USER_CONSUMER_ERROR_TYPES
|
|
@@ -107,7 +108,8 @@ module Karafka
|
|
|
107
108
|
[
|
|
108
109
|
%i[revoke revoked revoked],
|
|
109
110
|
%i[shutting_down shutdown shutdown],
|
|
110
|
-
%i[tick ticked tick]
|
|
111
|
+
%i[tick ticked tick],
|
|
112
|
+
%i[eof eofed eofed]
|
|
111
113
|
].each do |before, after, name|
|
|
112
114
|
class_eval <<~RUBY, __FILE__, __LINE__ + 1
|
|
113
115
|
# Keeps track of user code execution
|
|
@@ -35,6 +35,7 @@ module Karafka
|
|
|
35
35
|
def initialize(&block)
|
|
36
36
|
configure
|
|
37
37
|
setup(&block) if block
|
|
38
|
+
@job_types_cache = {}
|
|
38
39
|
end
|
|
39
40
|
|
|
40
41
|
# @param block [Proc] configuration block
|
|
@@ -51,28 +52,11 @@ module Karafka
|
|
|
51
52
|
push_tags
|
|
52
53
|
|
|
53
54
|
job = event[:job]
|
|
54
|
-
job_type = job.class
|
|
55
|
+
job_type = fetch_job_type(job.class)
|
|
55
56
|
consumer = job.executor.topic.consumer
|
|
56
57
|
topic = job.executor.topic.name
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
when 'Periodic'
|
|
60
|
-
'tick'
|
|
61
|
-
when 'PeriodicNonBlocking'
|
|
62
|
-
'tick'
|
|
63
|
-
when 'Shutdown'
|
|
64
|
-
'shutdown'
|
|
65
|
-
when 'Revoked'
|
|
66
|
-
'revoked'
|
|
67
|
-
when 'RevokedNonBlocking'
|
|
68
|
-
'revoked'
|
|
69
|
-
when 'Idle'
|
|
70
|
-
'idle'
|
|
71
|
-
else
|
|
72
|
-
'consume'
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
current_span.resource = "#{consumer}##{action}"
|
|
59
|
+
current_span.resource = "#{consumer}##{job.class.action}"
|
|
76
60
|
info "[#{job.id}] #{job_type} job for #{consumer} on #{topic} started"
|
|
77
61
|
|
|
78
62
|
pop_tags
|
|
@@ -121,6 +105,8 @@ module Karafka
|
|
|
121
105
|
error "Consumer on shutdown failed due to an error: #{error}"
|
|
122
106
|
when 'consumer.tick.error'
|
|
123
107
|
error "Consumer tick failed due to an error: #{error}"
|
|
108
|
+
when 'consumer.eofed.error'
|
|
109
|
+
error "Consumer eofed failed due to an error: #{error}"
|
|
124
110
|
when 'worker.process.error'
|
|
125
111
|
fatal "Worker processing failed due to an error: #{error}"
|
|
126
112
|
when 'connection.listener.fetch_loop.error'
|
|
@@ -169,6 +155,18 @@ module Karafka
|
|
|
169
155
|
|
|
170
156
|
Karafka.logger.pop_tags
|
|
171
157
|
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
# Takes the job class and extracts the job type.
|
|
162
|
+
# @param job_class [Class] job class
|
|
163
|
+
# @return [String]
|
|
164
|
+
# @note It does not have to be thread-safe despite running in multiple threads because
|
|
165
|
+
# the assignment race condition is irrelevant here since the same value will be
|
|
166
|
+
# assigned.
|
|
167
|
+
def fetch_job_type(job_class)
|
|
168
|
+
@job_types_cache[job_class] ||= job_class.to_s.split('::').last
|
|
169
|
+
end
|
|
172
170
|
end
|
|
173
171
|
end
|
|
174
172
|
end
|
|
@@ -82,10 +82,11 @@ module Karafka
|
|
|
82
82
|
statistics = event[:statistics]
|
|
83
83
|
consumer_group_id = event[:consumer_group_id]
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
tags = ["consumer_group:#{consumer_group_id}"]
|
|
86
|
+
tags.concat(default_tags)
|
|
86
87
|
|
|
87
88
|
rd_kafka_metrics.each do |metric|
|
|
88
|
-
report_metric(metric, statistics,
|
|
89
|
+
report_metric(metric, statistics, tags)
|
|
89
90
|
end
|
|
90
91
|
end
|
|
91
92
|
|
|
@@ -93,13 +94,14 @@ module Karafka
|
|
|
93
94
|
#
|
|
94
95
|
# @param event [Karafka::Core::Monitoring::Event]
|
|
95
96
|
def on_error_occurred(event)
|
|
96
|
-
|
|
97
|
+
tags = ["type:#{event[:type]}"]
|
|
98
|
+
tags.concat(default_tags)
|
|
97
99
|
|
|
98
100
|
if event.payload[:caller].respond_to?(:messages)
|
|
99
|
-
|
|
101
|
+
tags.concat(consumer_tags(event.payload[:caller]))
|
|
100
102
|
end
|
|
101
103
|
|
|
102
|
-
count('error_occurred', 1, tags:
|
|
104
|
+
count('error_occurred', 1, tags: tags)
|
|
103
105
|
end
|
|
104
106
|
|
|
105
107
|
# Reports how many messages we've polled and how much time did we spend on it
|
|
@@ -111,10 +113,11 @@ module Karafka
|
|
|
111
113
|
|
|
112
114
|
consumer_group_id = event[:subscription_group].consumer_group.id
|
|
113
115
|
|
|
114
|
-
|
|
116
|
+
tags = ["consumer_group:#{consumer_group_id}"]
|
|
117
|
+
tags.concat(default_tags)
|
|
115
118
|
|
|
116
|
-
histogram('listener.polling.time_taken', time_taken, tags:
|
|
117
|
-
histogram('listener.polling.messages', messages_count, tags:
|
|
119
|
+
histogram('listener.polling.time_taken', time_taken, tags: tags)
|
|
120
|
+
histogram('listener.polling.messages', messages_count, tags: tags)
|
|
118
121
|
end
|
|
119
122
|
|
|
120
123
|
# Here we report majority of things related to processing as we have access to the
|
|
@@ -125,7 +128,8 @@ module Karafka
|
|
|
125
128
|
messages = consumer.messages
|
|
126
129
|
metadata = messages.metadata
|
|
127
130
|
|
|
128
|
-
tags =
|
|
131
|
+
tags = consumer_tags(consumer)
|
|
132
|
+
tags.concat(default_tags)
|
|
129
133
|
|
|
130
134
|
count('consumer.messages', messages.count, tags: tags)
|
|
131
135
|
count('consumer.batches', 1, tags: tags)
|
|
@@ -146,7 +150,8 @@ module Karafka
|
|
|
146
150
|
#
|
|
147
151
|
# @param event [Karafka::Core::Monitoring::Event]
|
|
148
152
|
def on_consumer_#{after}(event)
|
|
149
|
-
tags =
|
|
153
|
+
tags = consumer_tags(event.payload[:caller])
|
|
154
|
+
tags.concat(default_tags)
|
|
150
155
|
|
|
151
156
|
count('consumer.#{name}', 1, tags: tags)
|
|
152
157
|
end
|
|
@@ -158,9 +163,10 @@ module Karafka
|
|
|
158
163
|
def on_worker_process(event)
|
|
159
164
|
jq_stats = event[:jobs_queue].statistics
|
|
160
165
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
histogram('worker.
|
|
166
|
+
tags = default_tags
|
|
167
|
+
gauge('worker.total_threads', Karafka::App.config.concurrency, tags: tags)
|
|
168
|
+
histogram('worker.processing', jq_stats[:busy], tags: tags)
|
|
169
|
+
histogram('worker.enqueued_jobs', jq_stats[:enqueued], tags: tags)
|
|
164
170
|
end
|
|
165
171
|
|
|
166
172
|
# We report this metric before and after processing for higher accuracy
|
|
@@ -240,11 +246,14 @@ module Karafka
|
|
|
240
246
|
# node ids
|
|
241
247
|
next if broker_statistics['nodeid'] == -1
|
|
242
248
|
|
|
249
|
+
tags = ["broker:#{broker_statistics['nodename']}"]
|
|
250
|
+
tags.concat(base_tags)
|
|
251
|
+
|
|
243
252
|
public_send(
|
|
244
253
|
metric.type,
|
|
245
254
|
metric.name,
|
|
246
255
|
broker_statistics.dig(*metric.key_location),
|
|
247
|
-
tags:
|
|
256
|
+
tags: tags
|
|
248
257
|
)
|
|
249
258
|
end
|
|
250
259
|
when :topics
|
|
@@ -259,14 +268,14 @@ module Karafka
|
|
|
259
268
|
next if partition_statistics['fetch_state'] == 'stopped'
|
|
260
269
|
next if partition_statistics['fetch_state'] == 'none'
|
|
261
270
|
|
|
271
|
+
tags = ["topic:#{topic_name}", "partition:#{partition_name}"]
|
|
272
|
+
tags.concat(base_tags)
|
|
273
|
+
|
|
262
274
|
public_send(
|
|
263
275
|
metric.type,
|
|
264
276
|
metric.name,
|
|
265
277
|
partition_statistics.dig(*metric.key_location),
|
|
266
|
-
tags:
|
|
267
|
-
"topic:#{topic_name}",
|
|
268
|
-
"partition:#{partition_name}"
|
|
269
|
-
]
|
|
278
|
+
tags: tags
|
|
270
279
|
)
|
|
271
280
|
end
|
|
272
281
|
end
|
|
@@ -29,13 +29,13 @@ module Karafka
|
|
|
29
29
|
@port = port
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
private
|
|
33
|
-
|
|
34
32
|
# @return [Boolean] true if all good, false if we should tell k8s to kill this process
|
|
35
33
|
def healthy?
|
|
36
34
|
raise NotImplementedError, 'Implement in a subclass'
|
|
37
35
|
end
|
|
38
36
|
|
|
37
|
+
private
|
|
38
|
+
|
|
39
39
|
# Responds to a HTTP request with the process liveness status
|
|
40
40
|
def respond
|
|
41
41
|
client = @server.accept
|
|
@@ -26,6 +26,19 @@ module Karafka
|
|
|
26
26
|
#
|
|
27
27
|
# @note Please use `Kubernetes::SwarmLivenessListener` when operating in the swarm mode
|
|
28
28
|
class LivenessListener < BaseListener
|
|
29
|
+
# When any of those occurs, it means something went wrong in a way that cannot be
|
|
30
|
+
# recovered. In such cases we should report that the consumer process is not healthy.
|
|
31
|
+
# - `fenced` - This instance has been fenced by a newer instance and will not do any
|
|
32
|
+
# processing at all never. Fencing most of the time means the instance.group.id has
|
|
33
|
+
# been reused without properly terminating the previous consumer process first
|
|
34
|
+
# - `fatal` - any fatal error that halts the processing forever
|
|
35
|
+
UNRECOVERABLE_RDKAFKA_ERRORS = [
|
|
36
|
+
:fenced, # -144
|
|
37
|
+
:fatal # -150
|
|
38
|
+
].freeze
|
|
39
|
+
|
|
40
|
+
private_constant :UNRECOVERABLE_RDKAFKA_ERRORS
|
|
41
|
+
|
|
29
42
|
# @param hostname [String, nil] hostname or nil to bind on all
|
|
30
43
|
# @param port [Integer] TCP port on which we want to run our HTTP status server
|
|
31
44
|
# @param consuming_ttl [Integer] time in ms after which we consider consumption hanging.
|
|
@@ -40,6 +53,11 @@ module Karafka
|
|
|
40
53
|
consuming_ttl: 5 * 60 * 1_000,
|
|
41
54
|
polling_ttl: 5 * 60 * 1_000
|
|
42
55
|
)
|
|
56
|
+
# If this is set to true, it indicates unrecoverable error like fencing
|
|
57
|
+
# While fencing can be partial (for one of the SGs), we still should consider this
|
|
58
|
+
# as an undesired state for the whole process because it halts processing in a
|
|
59
|
+
# non-recoverable manner forever
|
|
60
|
+
@unrecoverable = false
|
|
43
61
|
@polling_ttl = polling_ttl
|
|
44
62
|
@consuming_ttl = consuming_ttl
|
|
45
63
|
@mutex = Mutex.new
|
|
@@ -86,10 +104,19 @@ module Karafka
|
|
|
86
104
|
RUBY
|
|
87
105
|
end
|
|
88
106
|
|
|
89
|
-
# @param
|
|
90
|
-
def on_error_occurred(
|
|
107
|
+
# @param event [Karafka::Core::Monitoring::Event]
|
|
108
|
+
def on_error_occurred(event)
|
|
91
109
|
clear_consumption_tick
|
|
92
110
|
clear_polling_tick
|
|
111
|
+
|
|
112
|
+
error = event[:error]
|
|
113
|
+
|
|
114
|
+
# We are only interested in the rdkafka errors
|
|
115
|
+
return unless error.is_a?(Rdkafka::RdkafkaError)
|
|
116
|
+
# We mark as unrecoverable only on certain errors that will not be fixed by retrying
|
|
117
|
+
return unless UNRECOVERABLE_RDKAFKA_ERRORS.include?(error.code)
|
|
118
|
+
|
|
119
|
+
@unrecoverable = true
|
|
93
120
|
end
|
|
94
121
|
|
|
95
122
|
# Deregister the polling tracker for given listener
|
|
@@ -112,6 +139,18 @@ module Karafka
|
|
|
112
139
|
clear_polling_tick
|
|
113
140
|
end
|
|
114
141
|
|
|
142
|
+
# Did we exceed any of the ttls
|
|
143
|
+
# @return [String] 204 string if ok, 500 otherwise
|
|
144
|
+
def healthy?
|
|
145
|
+
time = monotonic_now
|
|
146
|
+
|
|
147
|
+
return false if @unrecoverable
|
|
148
|
+
return false if @pollings.values.any? { |tick| (time - tick) > @polling_ttl }
|
|
149
|
+
return false if @consumptions.values.any? { |tick| (time - tick) > @consuming_ttl }
|
|
150
|
+
|
|
151
|
+
true
|
|
152
|
+
end
|
|
153
|
+
|
|
115
154
|
private
|
|
116
155
|
|
|
117
156
|
# Wraps the logic with a mutex
|
|
@@ -152,17 +191,6 @@ module Karafka
|
|
|
152
191
|
@consumptions.delete(thread_id)
|
|
153
192
|
end
|
|
154
193
|
end
|
|
155
|
-
|
|
156
|
-
# Did we exceed any of the ttls
|
|
157
|
-
# @return [String] 204 string if ok, 500 otherwise
|
|
158
|
-
def healthy?
|
|
159
|
-
time = monotonic_now
|
|
160
|
-
|
|
161
|
-
return false if @pollings.values.any? { |tick| (time - tick) > @polling_ttl }
|
|
162
|
-
return false if @consumptions.values.any? { |tick| (time - tick) > @consuming_ttl }
|
|
163
|
-
|
|
164
|
-
true
|
|
165
|
-
end
|
|
166
194
|
end
|
|
167
195
|
end
|
|
168
196
|
end
|
|
@@ -8,15 +8,9 @@ module Karafka
|
|
|
8
8
|
# heavy-deserialization data without slowing down the whole application.
|
|
9
9
|
class Message
|
|
10
10
|
extend Forwardable
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
# @note We cache it here for performance reasons. It is 2.5x times faster than getting it
|
|
15
|
-
# via the config chain.
|
|
16
|
-
def parser
|
|
17
|
-
@parser ||= App.config.internal.messages.parser
|
|
18
|
-
end
|
|
19
|
-
end
|
|
11
|
+
extend Helpers::ConfigImporter.new(
|
|
12
|
+
parser: %i[internal messages parser]
|
|
13
|
+
)
|
|
20
14
|
|
|
21
15
|
attr_reader :metadata
|
|
22
16
|
# raw payload needs to be mutable as we want to have option to change it in the parser
|
|
@@ -51,6 +45,12 @@ module Karafka
|
|
|
51
45
|
@deserialized
|
|
52
46
|
end
|
|
53
47
|
|
|
48
|
+
# @return [Boolean] true if the message has a key and raw payload is nil, it is a tombstone
|
|
49
|
+
# event. Otherwise it is not.
|
|
50
|
+
def tombstone?
|
|
51
|
+
!raw_key.nil? && @raw_payload.nil?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
54
|
private
|
|
55
55
|
|
|
56
56
|
# @return [Object] deserialized data
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
-
# repository and their usage requires commercial license agreement.
|
|
8
|
-
#
|
|
9
|
-
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
-
#
|
|
11
|
-
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
-
# your code to Maciej Mensfeld.
|
|
3
|
+
# This code is part of Karafka Pro, a commercial component not licensed under LGPL.
|
|
4
|
+
# See LICENSE for details.
|
|
13
5
|
|
|
14
6
|
module Karafka
|
|
15
7
|
module Pro
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
-
# repository and their usage requires commercial license agreement.
|
|
8
|
-
#
|
|
9
|
-
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
-
#
|
|
11
|
-
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
-
# your code to Maciej Mensfeld.
|
|
3
|
+
# This code is part of Karafka Pro, a commercial component not licensed under LGPL.
|
|
4
|
+
# See LICENSE for details.
|
|
13
5
|
|
|
14
6
|
module Karafka
|
|
15
7
|
module Pro
|
|
@@ -28,14 +20,26 @@ module Karafka
|
|
|
28
20
|
# each job.
|
|
29
21
|
partitioner: nil,
|
|
30
22
|
# Allows for usage of `:key` or `:partition_key`
|
|
31
|
-
partition_key_type: :key
|
|
23
|
+
partition_key_type: :key,
|
|
24
|
+
# Topic to where this message should go when using scheduled messages. When defined,
|
|
25
|
+
# it will be used with `enqueue_at`. If not defined it will raise an error.
|
|
26
|
+
scheduled_messages_topic: nil,
|
|
27
|
+
# Allows for setting a callable producer since at the moment of defining the class,
|
|
28
|
+
# variants may not be available
|
|
29
|
+
#
|
|
30
|
+
# We do not initialize it with `-> { ::Karafka.producer }` so we do not have to call it
|
|
31
|
+
# each time for the defaults to preserve CPU cycles.
|
|
32
|
+
#
|
|
33
|
+
# We also do **not** cache the execution of this producer lambda because we want to
|
|
34
|
+
# support job args based producer selection
|
|
35
|
+
producer: nil
|
|
32
36
|
}.freeze
|
|
33
37
|
|
|
34
38
|
private_constant :DEFAULTS
|
|
35
39
|
|
|
36
40
|
# @param job [ActiveJob::Base] job
|
|
37
41
|
def dispatch(job)
|
|
38
|
-
|
|
42
|
+
producer(job).public_send(
|
|
39
43
|
fetch_option(job, :dispatch_method, DEFAULTS),
|
|
40
44
|
dispatch_details(job).merge!(
|
|
41
45
|
topic: job.queue_name,
|
|
@@ -47,27 +51,71 @@ module Karafka
|
|
|
47
51
|
# Bulk dispatches multiple jobs using the Rails 7.1+ API
|
|
48
52
|
# @param jobs [Array<ActiveJob::Base>] jobs we want to dispatch
|
|
49
53
|
def dispatch_many(jobs)
|
|
50
|
-
|
|
54
|
+
# First level is type of dispatch and second is the producer we want to use to dispatch
|
|
55
|
+
dispatches = Hash.new do |hash, key|
|
|
56
|
+
hash[key] = Hash.new do |hash2, key2|
|
|
57
|
+
hash2[key2] = []
|
|
58
|
+
end
|
|
59
|
+
end
|
|
51
60
|
|
|
52
61
|
jobs.each do |job|
|
|
53
62
|
d_method = fetch_option(job, :dispatch_many_method, DEFAULTS)
|
|
63
|
+
producer = producer(job)
|
|
54
64
|
|
|
55
|
-
dispatches[d_method] << dispatch_details(job).merge!(
|
|
65
|
+
dispatches[d_method][producer] << dispatch_details(job).merge!(
|
|
56
66
|
topic: job.queue_name,
|
|
57
67
|
payload: ::ActiveSupport::JSON.encode(serialize_job(job))
|
|
58
68
|
)
|
|
59
69
|
end
|
|
60
70
|
|
|
61
|
-
dispatches.each do |
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
dispatches.each do |d_method, producers|
|
|
72
|
+
producers.each do |producer, messages|
|
|
73
|
+
producer.public_send(
|
|
74
|
+
d_method,
|
|
75
|
+
messages
|
|
76
|
+
)
|
|
77
|
+
end
|
|
66
78
|
end
|
|
67
79
|
end
|
|
68
80
|
|
|
81
|
+
# Will enqueue a job to run in the future
|
|
82
|
+
#
|
|
83
|
+
# @param job [Object] job we want to enqueue
|
|
84
|
+
# @param timestamp [Time] time when job should run
|
|
85
|
+
def dispatch_at(job, timestamp)
|
|
86
|
+
target_message = dispatch_details(job).merge!(
|
|
87
|
+
topic: job.queue_name,
|
|
88
|
+
payload: ::ActiveSupport::JSON.encode(serialize_job(job))
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
proxy_message = Pro::ScheduledMessages.schedule(
|
|
92
|
+
message: target_message,
|
|
93
|
+
epoch: timestamp.to_i,
|
|
94
|
+
envelope: {
|
|
95
|
+
# Select the scheduled messages proxy topic
|
|
96
|
+
topic: fetch_option(job, :scheduled_messages_topic, DEFAULTS)
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
producer(job).public_send(
|
|
101
|
+
fetch_option(job, :dispatch_method, DEFAULTS),
|
|
102
|
+
proxy_message
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
69
106
|
private
|
|
70
107
|
|
|
108
|
+
# Selects the producer based on options. If callable `:producer` is defined, it will use
|
|
109
|
+
# it. If not, will just use the `Karafka.producer`.
|
|
110
|
+
#
|
|
111
|
+
# @param job [ActiveJob::Base] job instance
|
|
112
|
+
# @return [WaterDrop::Producer, WaterDrop::Producer::Variant] producer or a variant
|
|
113
|
+
def producer(job)
|
|
114
|
+
dynamic_producer = fetch_option(job, :producer, DEFAULTS)
|
|
115
|
+
|
|
116
|
+
dynamic_producer ? dynamic_producer.call(job) : ::Karafka.producer
|
|
117
|
+
end
|
|
118
|
+
|
|
71
119
|
# @param job [ActiveJob::Base] job instance
|
|
72
120
|
# @return [Hash] hash with dispatch details to which we merge topic and payload
|
|
73
121
|
def dispatch_details(job)
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
-
# repository and their usage requires commercial license agreement.
|
|
8
|
-
#
|
|
9
|
-
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
-
#
|
|
11
|
-
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
-
# your code to Maciej Mensfeld.
|
|
3
|
+
# This code is part of Karafka Pro, a commercial component not licensed under LGPL.
|
|
4
|
+
# See LICENSE for details.
|
|
13
5
|
|
|
14
6
|
module Karafka
|
|
15
7
|
module Pro
|
|
@@ -25,14 +17,24 @@ module Karafka
|
|
|
25
17
|
).fetch('en').fetch('validations').fetch('job_options')
|
|
26
18
|
end
|
|
27
19
|
|
|
20
|
+
optional(:producer) { |val| val.nil? || val.respond_to?(:call) }
|
|
28
21
|
optional(:partitioner) { |val| val.respond_to?(:call) }
|
|
29
22
|
optional(:partition_key_type) { |val| %i[key partition_key partition].include?(val) }
|
|
23
|
+
|
|
24
|
+
# Whether this is a legit scheduled messages topic will be validated during the first
|
|
25
|
+
# dispatch, so we do not repeat validations here
|
|
26
|
+
optional(:scheduled_messages_topic) do |val|
|
|
27
|
+
(val.is_a?(String) || val.is_a?(Symbol)) &&
|
|
28
|
+
::Karafka::Contracts::TOPIC_REGEXP.match?(val.to_s)
|
|
29
|
+
end
|
|
30
|
+
|
|
30
31
|
optional(:dispatch_method) do |val|
|
|
31
32
|
%i[
|
|
32
33
|
produce_async
|
|
33
34
|
produce_sync
|
|
34
35
|
].include?(val)
|
|
35
36
|
end
|
|
37
|
+
|
|
36
38
|
optional(:dispatch_many_method) do |val|
|
|
37
39
|
%i[
|
|
38
40
|
produce_many_async
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
-
# repository and their usage requires commercial license agreement.
|
|
8
|
-
#
|
|
9
|
-
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
-
#
|
|
11
|
-
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
-
# your code to Maciej Mensfeld.
|
|
3
|
+
# This code is part of Karafka Pro, a commercial component not licensed under LGPL.
|
|
4
|
+
# See LICENSE for details.
|
|
13
5
|
|
|
14
6
|
module Karafka
|
|
15
7
|
module Pro
|
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# This
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# All of the commercial components are present in the lib/karafka/pro directory of this
|
|
7
|
-
# repository and their usage requires commercial license agreement.
|
|
8
|
-
#
|
|
9
|
-
# Karafka has also commercial-friendly license, commercial support and commercial components.
|
|
10
|
-
#
|
|
11
|
-
# By sending a pull request to the pro components, you are agreeing to transfer the copyright of
|
|
12
|
-
# your code to Maciej Mensfeld.
|
|
3
|
+
# This code is part of Karafka Pro, a commercial component not licensed under LGPL.
|
|
4
|
+
# See LICENSE for details.
|
|
13
5
|
|
|
14
6
|
module Karafka
|
|
15
7
|
module Pro
|