karafka 2.5.3 → 2.5.4.rc1

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/config/locales/errors.yml +14 -0
  4. data/karafka.gemspec +13 -2
  5. data/lib/karafka/admin/contracts/replication.rb +149 -0
  6. data/lib/karafka/admin/replication.rb +462 -0
  7. data/lib/karafka/admin.rb +47 -2
  8. data/lib/karafka/instrumentation/logger_listener.rb +0 -2
  9. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +4 -0
  10. data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +31 -15
  11. data/lib/karafka/licenser.rb +1 -1
  12. data/lib/karafka/messages/messages.rb +32 -0
  13. data/lib/karafka/pro/cleaner/messages/messages.rb +1 -1
  14. data/lib/karafka/pro/processing/jobs_queue.rb +0 -2
  15. data/lib/karafka/pro/processing/strategies/dlq/default.rb +1 -1
  16. data/lib/karafka/pro/processing/strategies/vp/default.rb +1 -1
  17. data/lib/karafka/processing/strategies/dlq.rb +1 -1
  18. data/lib/karafka/routing/consumer_group.rb +19 -1
  19. data/lib/karafka/routing/subscription_group.rb +1 -1
  20. data/lib/karafka/routing/subscription_groups_builder.rb +17 -2
  21. data/lib/karafka/version.rb +1 -1
  22. data/lib/karafka.rb +0 -1
  23. metadata +3 -62
  24. data/.coditsu/ci.yml +0 -3
  25. data/.console_irbrc +0 -11
  26. data/.github/CODEOWNERS +0 -3
  27. data/.github/FUNDING.yml +0 -1
  28. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -43
  29. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  30. data/.github/workflows/ci_linux_ubuntu_x86_64_gnu.yml +0 -296
  31. data/.github/workflows/ci_macos_arm64.yml +0 -151
  32. data/.github/workflows/push.yml +0 -35
  33. data/.github/workflows/trigger-wiki-refresh.yml +0 -30
  34. data/.github/workflows/verify-action-pins.yml +0 -16
  35. data/.gitignore +0 -69
  36. data/.rspec +0 -7
  37. data/.ruby-gemset +0 -1
  38. data/.ruby-version +0 -1
  39. data/.yard-lint.yml +0 -174
  40. data/CODE_OF_CONDUCT.md +0 -46
  41. data/CONTRIBUTING.md +0 -32
  42. data/Gemfile +0 -29
  43. data/Gemfile.lock +0 -178
  44. data/Rakefile +0 -4
  45. data/SECURITY.md +0 -23
  46. data/bin/benchmarks +0 -99
  47. data/bin/clean_kafka +0 -43
  48. data/bin/create_token +0 -22
  49. data/bin/integrations +0 -341
  50. data/bin/record_rss +0 -50
  51. data/bin/rspecs +0 -26
  52. data/bin/scenario +0 -29
  53. data/bin/stress_many +0 -13
  54. data/bin/stress_one +0 -13
  55. data/bin/verify_kafka_warnings +0 -36
  56. data/bin/verify_license_integrity +0 -37
  57. data/bin/verify_topics_naming +0 -27
  58. data/bin/wait_for_kafka +0 -24
  59. data/docker-compose.yml +0 -25
  60. data/examples/payloads/avro/.gitkeep +0 -0
  61. data/examples/payloads/json/sample_set_01/enrollment_event.json +0 -579
  62. data/examples/payloads/json/sample_set_01/ingestion_event.json +0 -30
  63. data/examples/payloads/json/sample_set_01/transaction_event.json +0 -17
  64. data/examples/payloads/json/sample_set_01/user_event.json +0 -11
  65. data/examples/payloads/json/sample_set_02/download.json +0 -191
  66. data/examples/payloads/json/sample_set_03/event_type_1.json +0 -18
  67. data/examples/payloads/json/sample_set_03/event_type_2.json +0 -263
  68. data/examples/payloads/json/sample_set_03/event_type_3.json +0 -41
  69. data/log/.gitkeep +0 -0
  70. data/renovate.json +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d7b2a6d732bc69e537d14e306a4edc922b6375aa0154dada74527b06efea34fa
4
- data.tar.gz: 2e6c1f533f706d70699db822d6d34eac5b6df0c0275bc12366238cc7316a3793
3
+ metadata.gz: 974c54eac8c3f6045b0eb6f21cde51b48cd8a23af18efd640784870045c01d35
4
+ data.tar.gz: d22621e0199bf8e1adbfe67f59247d2f8e5ae61a52fc389ea1baa2d4f8401418
5
5
  SHA512:
6
- metadata.gz: c760fb9e76f6e3af5421cfc0d821d03c3c845c629ea4ab1b2bcfa89c50431320b5cada72482eb48dfc9c27718631e1920ca5133ccd3884daddbc84cc6a7288e7
7
- data.tar.gz: ce5466e71edc225b9e11283be5f7e1f877f6222a766dd63f69a235a0739a812f5007da341f5010a71eb2322efebb400fa441a7188f41ac6c244acade0b37c4e4
6
+ metadata.gz: f81840332313f5914afde17caeaa794085442ac702e62ea4b6a51429cc191ac2cd7562181a55b76bc314fcc0ca6411c27308cc7b0b88637cdece4a8b1e5c75e4
7
+ data.tar.gz: acbc167ab3314dc884274992cd17d40256c967ab1a2ad141376565b1164b29a11669a9ebabe79125ac7129103d9fb09447441bc992b8540115576fa906b033a5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Karafka Framework Changelog
2
2
 
3
+ ## 2.5.4 (Unreleased)
4
+ - [Enhancement] Align Datadog logger listener error handling with the main logger listener by adding missing error types and replacing `UnsupportedCaseError` with generic error logging to support dynamic errors reporting.
5
+ - [Enhancement] Align Appsignal metrics listener `USER_CONSUMER_ERROR_TYPES` with all consumer error types for complete error tracking.
6
+ - [Enhancement] Reduce gem package size by excluding development files (spec, examples, CI configs, dev scripts) from the gem build.
7
+ - [Fix] Multiple route draws don't seem to work.
8
+ - [Fix] Fix internal code compatibility with external libraries that prepend modules to `Messages#each` method (e.g., DataDog tracing) by introducing `Messages#raw` for internal iteration that bypasses patched enumerable methods.
9
+ - [Maintenance] Removed `base64` dependency.
10
+ - [Maintenance] Add `ErrorTypesChecker` spec support module to programmatically verify listener error type coverage against source code definitions.
11
+
3
12
  ## 2.5.3 (2025-11-14)
4
13
  - [Enhancement] Dynamically support `librdkafka` fatal errors with correct reported details.
5
14
  - [Enhancement] Add `producer` block API to setup for simplified WaterDrop producer configuration without manual producer instance creation, using a transparent ConfigProxy during setup to avoid polluting the permanent config API.
@@ -10,6 +19,7 @@
10
19
  - **[EOL]** Remove Rails 7.1 support according to EOL while not blocking Rails 7.1 usage.
11
20
  - [Enhancement] Retry on the KIP-848 `stale_member_epoch` error.
12
21
  - [Enhancement] Provide `Karafka::Admin.trigger_rebalance` API to programmatically trigger consumer group rebalances for operational purposes.
22
+ - [Enhancement] Provide `Karafka::Admin.plan_topic_replication` API to generate partition reassignment plans for increasing topic replication factors with automatic broker distribution or manual placement, compatible with `kafka-reassign-partitions.sh` tool.
13
23
  - [Enhancement] Nest pause configuration under `config.pause.*` namespace (`config.pause.timeout`, `config.pause.max_timeout`, `config.pause.with_exponential_backoff`) while maintaining backwards compatibility with the old flat API (`config.pause_timeout`, etc.) via delegation methods that will be removed in Karafka 2.6.
14
24
  - [Enhancement] Detect and track involuntary assignment loss during long-running processing that exceeds `max.poll.interval.ms` via `client.events_poll` event and automatically update `Karafka::App.assignments` to reflect reality.
15
25
  - [Enhancement] Extend `Karafka::Admin.read_watermark_offsets` to accept either a single topic with partition or a hash of multiple topics with partitions, using a single consumer instance for improved efficiency when querying multiple partitions.
@@ -100,6 +100,20 @@ en:
100
100
  topics_inclusion: Unknown topic name
101
101
  topics_missing: No topics to subscribe to
102
102
 
103
+ admin:
104
+ replication:
105
+ missing: needs to be present
106
+ topic_format: needs to be a non-empty string
107
+ to_format: needs to be an integer greater than 0
108
+ brokers_format: needs to be a hash when provided
109
+ must_be_higher_than_current: target replication factor must be higher than current
110
+ exceeds_broker_count: target replication factor cannot exceed available broker count
111
+ missing_partitions: manual assignment missing partitions
112
+ invalid_partition: partition does not exist in topic
113
+ wrong_broker_count_for_partition: partition broker count does not match target replication factor
114
+ duplicate_brokers_for_partition: partition has duplicate brokers
115
+ invalid_brokers_for_partition: partition references non-existent brokers
116
+
103
117
  routing:
104
118
  without_declarative_definition: lacks explicit declarative topics definition
105
119
 
data/karafka.gemspec CHANGED
@@ -21,7 +21,6 @@ Gem::Specification.new do |spec|
21
21
  without having to focus on things that are not your business domain.
22
22
  DESC
23
23
 
24
- spec.add_dependency 'base64', '~> 0.2'
25
24
  spec.add_dependency 'karafka-core', '>= 2.5.6', '< 2.6.0'
26
25
  spec.add_dependency 'karafka-rdkafka', '>= 0.23.1'
27
26
  spec.add_dependency 'waterdrop', '>= 2.8.14', '< 3.0.0'
@@ -29,7 +28,19 @@ Gem::Specification.new do |spec|
29
28
 
30
29
  spec.required_ruby_version = '>= 3.2.0'
31
30
 
32
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec)/}) }
31
+ gem_files = %w[
32
+ lib/**/*
33
+ bin/karafka
34
+ certs/*
35
+ config/**/*
36
+ LICENSE*
37
+ CHANGELOG.md
38
+ README.md
39
+ karafka.gemspec
40
+ ]
41
+
42
+ spec.files = Dir.glob(gem_files) & `git ls-files -z`.split("\x0")
43
+
33
44
  spec.executables = %w[karafka]
34
45
  spec.require_paths = %w[lib]
35
46
 
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ class Admin
5
+ # Contracts namespace for Admin validation logic
6
+ module Contracts
7
+ # Contract for replication plan parameters
8
+ class Replication < Karafka::Contracts::Base
9
+ configure do |config|
10
+ config.error_messages = YAML.safe_load_file(
11
+ File.join(Karafka.gem_root, 'config', 'locales', 'errors.yml')
12
+ ).fetch('en').fetch('validations').fetch('admin').fetch('replication')
13
+ end
14
+
15
+ required(:topic) { |val| val.is_a?(String) && !val.empty? }
16
+ required(:to) { |val| val.is_a?(Integer) && val >= 1 }
17
+ optional(:brokers) { |val| val.nil? || val.is_a?(Hash) }
18
+
19
+ # Validate that target replication factor is higher than current
20
+ virtual do |data, errors|
21
+ next unless errors.empty?
22
+ next unless data.key?(:current_rf)
23
+
24
+ target_rf = data.fetch(:to)
25
+ current_rf = data.fetch(:current_rf)
26
+
27
+ next if target_rf > current_rf
28
+
29
+ [[%w[to], :must_be_higher_than_current]]
30
+ end
31
+
32
+ # Validate that target replication factor doesn't exceed available brokers
33
+ virtual do |data, errors|
34
+ next unless errors.empty?
35
+ next unless data.key?(:broker_count)
36
+
37
+ target_rf = data.fetch(:to)
38
+ broker_count = data.fetch(:broker_count)
39
+
40
+ next if target_rf <= broker_count
41
+
42
+ [[%w[to], :exceeds_broker_count]]
43
+ end
44
+
45
+ # Validate all partitions are specified in manual broker assignment
46
+ virtual do |data, errors|
47
+ next unless errors.empty?
48
+
49
+ brokers = data[:brokers]
50
+ next if brokers.nil?
51
+ next unless data.key?(:topic_info)
52
+
53
+ topic_info = data.fetch(:topic_info)
54
+ partition_ids = topic_info.fetch(:partitions, []).map { |p| p[:partition_id] }
55
+
56
+ missing_partitions = partition_ids - brokers.keys
57
+ next unless missing_partitions.any?
58
+
59
+ [[%w[brokers], :missing_partitions]]
60
+ end
61
+
62
+ # Validate that manual broker assignments reference valid partitions
63
+ virtual do |data, errors|
64
+ next unless errors.empty?
65
+
66
+ brokers = data[:brokers]
67
+ next if brokers.nil?
68
+ next unless data.key?(:topic_info)
69
+
70
+ topic_info = data.fetch(:topic_info)
71
+ partition_ids = topic_info.fetch(:partitions, []).map { |p| p[:partition_id] }
72
+
73
+ error_found = nil
74
+ brokers.each_key do |partition_id|
75
+ unless partition_ids.include?(partition_id)
76
+ error_found = [[%w[brokers], :invalid_partition]]
77
+ break
78
+ end
79
+ end
80
+
81
+ error_found
82
+ end
83
+
84
+ # Validate broker count matches target replication factor for each partition
85
+ virtual do |data, errors|
86
+ next unless errors.empty?
87
+
88
+ brokers = data[:brokers]
89
+ next if brokers.nil?
90
+ next unless data.key?(:topic_info)
91
+
92
+ target_rf = data.fetch(:to)
93
+
94
+ error_found = nil
95
+ brokers.each_value do |broker_ids|
96
+ if broker_ids.size != target_rf
97
+ error_found = [[%w[brokers], :wrong_broker_count_for_partition]]
98
+ break
99
+ end
100
+ end
101
+
102
+ error_found
103
+ end
104
+
105
+ # Validate no duplicate brokers assigned to the same partition
106
+ virtual do |data, errors|
107
+ next unless errors.empty?
108
+
109
+ brokers = data[:brokers]
110
+ next if brokers.nil?
111
+ next unless data.key?(:topic_info)
112
+
113
+ error_found = nil
114
+ brokers.each_value do |broker_ids|
115
+ if broker_ids.size != broker_ids.uniq.size
116
+ error_found = [[%w[brokers], :duplicate_brokers_for_partition]]
117
+ break
118
+ end
119
+ end
120
+
121
+ error_found
122
+ end
123
+
124
+ # Validate all referenced brokers exist in the cluster
125
+ virtual do |data, errors|
126
+ next unless errors.empty?
127
+
128
+ brokers = data[:brokers]
129
+ next if brokers.nil?
130
+ next unless data.key?(:topic_info)
131
+
132
+ cluster_info = data.fetch(:cluster_info, {})
133
+ all_broker_ids = cluster_info.fetch(:brokers, []).map { |b| b[:node_id] }
134
+
135
+ error_found = nil
136
+ brokers.each_value do |broker_ids|
137
+ invalid_brokers = broker_ids - all_broker_ids
138
+ if invalid_brokers.any?
139
+ error_found = [[%w[brokers], :invalid_brokers_for_partition]]
140
+ break
141
+ end
142
+ end
143
+
144
+ error_found
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end