karafka 2.6.0.beta1 → 2.6.0.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 (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -27
  3. data/certs/expired.txt +2 -0
  4. data/config/locales/errors.yml +5 -0
  5. data/karafka.gemspec +1 -1
  6. data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -1
  7. data/lib/karafka/active_job/current_attributes/loading.rb +1 -1
  8. data/lib/karafka/active_job/current_attributes.rb +4 -2
  9. data/lib/karafka/active_job/dispatcher.rb +1 -2
  10. data/lib/karafka/admin/consumer_groups.rb +8 -2
  11. data/lib/karafka/admin/replication.rb +6 -3
  12. data/lib/karafka/admin/topics.rb +32 -12
  13. data/lib/karafka/admin.rb +155 -59
  14. data/lib/karafka/app.rb +1 -1
  15. data/lib/karafka/base_consumer.rb +33 -5
  16. data/lib/karafka/cli/console.rb +0 -1
  17. data/lib/karafka/cli/help.rb +0 -1
  18. data/lib/karafka/cli/info.rb +0 -1
  19. data/lib/karafka/cli/install.rb +0 -1
  20. data/lib/karafka/cli/server.rb +0 -1
  21. data/lib/karafka/cli/swarm.rb +0 -1
  22. data/lib/karafka/cli.rb +2 -2
  23. data/lib/karafka/connection/client.rb +44 -7
  24. data/lib/karafka/connection/listener.rb +3 -3
  25. data/lib/karafka/connection/manager.rb +0 -1
  26. data/lib/karafka/connection/pauses_manager.rb +17 -0
  27. data/lib/karafka/connection/proxy.rb +45 -0
  28. data/lib/karafka/connection/status.rb +0 -1
  29. data/lib/karafka/instrumentation/assignments_tracker.rb +34 -0
  30. data/lib/karafka/instrumentation/callbacks/consumer_groups/decorator.rb +19 -0
  31. data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +0 -1
  32. data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +3 -2
  33. data/lib/karafka/instrumentation/critical_errors_listener.rb +85 -0
  34. data/lib/karafka/instrumentation/logger_listener.rb +2 -0
  35. data/lib/karafka/instrumentation/monitor.rb +2 -3
  36. data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +0 -1
  37. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +0 -1
  38. data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +4 -3
  39. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +0 -2
  40. data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +181 -18
  41. data/lib/karafka/pro/admin/recovery/errors.rb +0 -1
  42. data/lib/karafka/pro/admin/recovery.rb +6 -4
  43. data/lib/karafka/pro/base_consumer.rb +5 -5
  44. data/lib/karafka/pro/cleaner/messages/metadata.rb +0 -1
  45. data/lib/karafka/pro/cli/parallel_segments/base.rb +1 -2
  46. data/lib/karafka/pro/connection/manager.rb +7 -4
  47. data/lib/karafka/pro/encryption/messages/middleware.rb +5 -0
  48. data/lib/karafka/pro/encryption/messages/parser.rb +4 -0
  49. data/lib/karafka/pro/instrumentation/callbacks/consumer_groups/decorator.rb +63 -0
  50. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/compensator.rb +120 -0
  51. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/fetcher.rb +88 -0
  52. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/refresher.rb +185 -0
  53. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/registry.rb +102 -0
  54. data/lib/karafka/pro/instrumentation/performance_tracker.rb +40 -6
  55. data/lib/karafka/pro/iterator/tpl_builder.rb +27 -7
  56. data/lib/karafka/pro/iterator.rb +22 -7
  57. data/lib/karafka/pro/loader.rb +12 -0
  58. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +0 -3
  59. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +2 -4
  60. data/lib/karafka/pro/processing/consumer_groups/collapser.rb +6 -9
  61. data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +1 -4
  62. data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +0 -3
  63. data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +21 -10
  64. data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +4 -4
  65. data/lib/karafka/pro/processing/consumer_groups/expansions_selector.rb +0 -3
  66. data/lib/karafka/pro/processing/consumer_groups/filters/actions.rb +84 -0
  67. data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +5 -6
  68. data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +2 -5
  69. data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +1 -4
  70. data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +1 -4
  71. data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +2 -5
  72. data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +0 -3
  73. data/lib/karafka/pro/processing/consumer_groups/jobs/consume_non_blocking.rb +2 -3
  74. data/lib/karafka/pro/processing/consumer_groups/jobs/eofed_non_blocking.rb +0 -2
  75. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +2 -3
  76. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic_non_blocking.rb +0 -2
  77. data/lib/karafka/pro/processing/consumer_groups/jobs/revoked_non_blocking.rb +0 -3
  78. data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +5 -4
  79. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +3 -7
  80. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +8 -10
  81. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +0 -3
  82. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +3 -5
  83. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +0 -3
  84. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +0 -3
  85. data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +2 -5
  86. data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +2 -5
  87. data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +2 -5
  88. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +10 -9
  89. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +11 -10
  90. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +0 -3
  91. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +0 -3
  92. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom.rb +8 -7
  93. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +9 -8
  94. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +5 -8
  95. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +3 -6
  96. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom.rb +4 -7
  97. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +6 -9
  98. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom.rb +3 -7
  99. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +4 -8
  100. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom.rb +3 -6
  101. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +4 -7
  102. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +2 -5
  103. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +3 -6
  104. data/lib/karafka/pro/processing/consumer_groups/strategies/base.rb +0 -3
  105. data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +56 -33
  106. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +27 -14
  107. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr.rb +0 -3
  108. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +4 -7
  109. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +5 -8
  110. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb +5 -8
  111. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +3 -7
  112. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +0 -3
  113. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +0 -3
  114. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_vp.rb +0 -3
  115. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +2 -5
  116. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +0 -3
  117. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom_vp.rb +0 -3
  118. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +3 -6
  119. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +0 -3
  120. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom_vp.rb +3 -6
  121. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +65 -8
  122. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +0 -4
  123. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/vp.rb +2 -5
  124. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +0 -3
  125. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +3 -6
  126. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +4 -7
  127. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +4 -8
  128. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +3 -6
  129. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +2 -5
  130. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +3 -7
  131. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/vp.rb +2 -5
  132. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/default.rb +0 -3
  133. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr.rb +0 -3
  134. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr_vp.rb +0 -3
  135. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/vp.rb +0 -3
  136. data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +11 -6
  137. data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +0 -3
  138. data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +0 -3
  139. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +0 -3
  140. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +2 -4
  141. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/consistent.rb +0 -3
  142. data/lib/karafka/pro/processing/jobs_queue.rb +4 -1
  143. data/lib/karafka/pro/processing/schedulers/base.rb +4 -2
  144. data/lib/karafka/pro/processing/schedulers/default.rb +2 -2
  145. data/lib/karafka/pro/recurring_tasks/consumer.rb +9 -2
  146. data/lib/karafka/pro/recurring_tasks/contracts/config.rb +0 -1
  147. data/lib/karafka/pro/recurring_tasks/executor.rb +25 -13
  148. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +0 -2
  149. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job.rb +0 -2
  150. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/proxy.rb +2 -2
  151. data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job.rb +0 -2
  152. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +0 -6
  153. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +5 -4
  154. data/lib/karafka/pro/routing/features/consumer_groups/patterns/config.rb +0 -6
  155. data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +2 -1
  156. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/pattern.rb +0 -1
  157. data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +2 -1
  158. data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +2 -1
  159. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +8 -8
  160. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +5 -5
  161. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +33 -13
  162. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +52 -28
  163. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +2 -1
  164. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +6 -5
  165. data/lib/karafka/pro/scheduled_messages/consumer.rb +7 -1
  166. data/lib/karafka/pro/scheduled_messages/schema_validator.rb +6 -1
  167. data/lib/karafka/pro/swarm/liveness_listener.rb +118 -13
  168. data/lib/karafka/pro.rb +0 -6
  169. data/lib/karafka/processing/consumer_groups/coordinator.rb +4 -5
  170. data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +6 -2
  171. data/lib/karafka/processing/consumer_groups/executor.rb +4 -4
  172. data/lib/karafka/processing/consumer_groups/executors_buffer.rb +2 -4
  173. data/lib/karafka/processing/consumer_groups/expansions_selector.rb +0 -2
  174. data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +0 -2
  175. data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +0 -2
  176. data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +14 -16
  177. data/lib/karafka/processing/consumer_groups/jobs/consume.rb +2 -5
  178. data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +2 -3
  179. data/lib/karafka/processing/consumer_groups/jobs/idle.rb +2 -2
  180. data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +2 -4
  181. data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +2 -2
  182. data/lib/karafka/processing/consumer_groups/partitioner.rb +3 -6
  183. data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +5 -2
  184. data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +2 -4
  185. data/lib/karafka/processing/consumer_groups/strategies/base.rb +3 -5
  186. data/lib/karafka/processing/consumer_groups/strategies/default.rb +43 -13
  187. data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +5 -2
  188. data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +5 -2
  189. data/lib/karafka/processing/consumer_groups/strategies/mom.rb +2 -3
  190. data/lib/karafka/processing/consumer_groups/strategy_selector.rb +0 -2
  191. data/lib/karafka/processing/coordinator.rb +0 -2
  192. data/lib/karafka/processing/coordinators_buffer.rb +0 -2
  193. data/lib/karafka/processing/partitioner.rb +0 -2
  194. data/lib/karafka/processing/strategy_selector.rb +0 -2
  195. data/lib/karafka/processing/worker.rb +14 -6
  196. data/lib/karafka/processing/workers_pool.rb +21 -4
  197. data/lib/karafka/railtie.rb +0 -1
  198. data/lib/karafka/routing/contracts/routing.rb +2 -2
  199. data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +6 -5
  200. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +2 -2
  201. data/lib/karafka/routing/features/deserializers/topic.rb +0 -1
  202. data/lib/karafka/routing/subscription_group.rb +1 -1
  203. data/lib/karafka/routing/topic.rb +4 -4
  204. data/lib/karafka/routing/topics.rb +21 -1
  205. data/lib/karafka/server.rb +9 -0
  206. data/lib/karafka/setup/config.rb +54 -10
  207. data/lib/karafka/setup/config_proxy.rb +2 -1
  208. data/lib/karafka/setup/contracts/config.rb +14 -0
  209. data/lib/karafka/swarm/node.rb +2 -2
  210. data/lib/karafka/version.rb +1 -2
  211. data/lib/karafka.rb +2 -2
  212. metadata +12 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 04dfc2086393c6d3d1b8c78eca503c425842453163b014dcba68a5c4231fe090
4
- data.tar.gz: 5f62160e469b6eb2383234f630654b46fe704e9dedd896e863771c945ab8e30e
3
+ metadata.gz: bc797708a61eca1cc0309dce91d05ab1dd623f3c7f6abfd74ac7af69c98f5254
4
+ data.tar.gz: 9e0e3bace7cc9f5393dfe788035ddc6e89cd64c8afd7ed5a2400d841cce95637
5
5
  SHA512:
6
- metadata.gz: 3f1bb0b95294bb925b71ff4cd91d0603b538b4f7f9a222a4789aa9aeef89f7f80b8b26ebf2623f1c44585e1de1d87d4be6dbb55748f61de9b1dd90cab68059d7
7
- data.tar.gz: 1c79e3b072d6b53c0062f0ade986f357f677cae6d476297389732c3c130fd89e84687526729ba2590763d15d5f0279e08e3ca9fceec386401b2d9d5ec3ef2096
6
+ metadata.gz: 512bed7912b22916225f0428cf1ef949e534765eaca459606155e451566e847c3c0993a83978f230f72ac202e2d6e797415df4086ed00b37bfdbcdb94f5f4e06
7
+ data.tar.gz: f0152dec64b5ba30ebae473db2236848b6a3298473be0dec7956330e44e973593311a70e616eb68cc8705fdbcdf55a53eff1d54a230658a0307d7ba6b00cb413
data/CHANGELOG.md CHANGED
@@ -1,38 +1,75 @@
1
1
  # Karafka Framework Changelog
2
2
 
3
3
  ## 2.6.0 (Unreleased)
4
- - [Maintenance] Replace manual per-version `Warning[:performance]` / `Warning[:deprecated]` flag setup in specs with a dynamic `Warning.categories`-based approach that enables all non-experimental warning categories automatically, keeping spec warning configuration in sync with karafka-rdkafka.
5
- - [Enhancement] Replace per-partition `query_watermark_offsets` consumer calls in `Admin::Topics#read_watermark_offsets` with two batch `list_offsets` admin calls (`:earliest` and `:latest`), reducing N sequential consumer roundtrips to 2 admin roundtrips regardless of how many topics or partitions are queried. Replace per-partition `query_watermark_offsets` fallback in `Admin::ConsumerGroups#seek` (when a time-based offset resolves beyond the last message) with a single batch `list_offsets` call covering all affected partitions. Replace per-partition `query_watermark_offsets` loop in `Pro::Iterator::TplBuilder#resolve_partitions_with_negative_offsets` with one batched `offsets_for_times(epoch)` call for consumer metadata warm-up plus two batch admin `list_offsets` calls for LWM/HWM resolution, reducing N sequential calls to 3 total (Pro).
6
- - **[Feature]** Add `Karafka::Admin.read_partition_offsets` (and `Admin::Topics#read_partition_offsets`) to expose the `rd_kafka_ListOffsets` admin API. Allows querying partition offsets by spec (`:earliest`, `:latest`, `:max_timestamp`, or a timestamp in ms) without a consumer group. Accepts an optional `isolation_level:` keyword — pass `Karafka::Admin::IsolationLevels::READ_COMMITTED` to get the Last Stable Offset (LSO) instead of the high-watermark, giving accurate lag figures on transactionally-produced topics.
7
- - **[Feature]** Add `Karafka::Admin::IsolationLevels` module with `READ_UNCOMMITTED` and `READ_COMMITTED` constants. These wrap the underlying `Rdkafka::Bindings` integer constants so callers do not need to reference rdkafka internals directly.
8
- - **[Feature]** Introduce standalone `Karafka::Declaratives` subsystem (`Declaratives::Topic`, `Declaratives::Repository`, `Declaratives::Builder`) decoupled from routing. Topic declarations can now be defined via `Karafka::App.declaratives.draw` independently of routing blocks. The existing `routing#config(partitions:, ...)` DSL continues to work as a backwards-compatible bridge that populates the shared declaratives repository.
9
- - [Enhancement] CLI topic commands (`create`, `delete`, `reset`, `repartition`, `align`, `migrate`, `plan`) now read from `Karafka::App.declaratives.topics` instead of walking the routing tree. Topics declared via the standalone `declaratives.draw` DSL are now managed by all CLI commands without requiring a routing entry. The routing bridge sets `bootstrap_servers` on declarations for cluster filtering.
10
- - [Enhancement] Move consumer-group-specific `Processing` components (`Coordinator`, `CoordinatorsBuffer`, `Executor`, `ExecutorsBuffer`, `Partitioner`, `ExpansionsSelector`, `InlineInsights`) and Pro equivalents (including `SubscriptionGroupsCoordinator`, `Collapser`, `AdaptiveIterator`, `PeriodicJob`, `ParallelSegments`, `VirtualPartitions`, `Filters`, `OffsetMetadata`, `Piping`) under the `ConsumerGroups` namespace (internal). The `config.processing.coordinator_class`, `executor_class`, `partitioner_class`, and `expansions_selector` defaults are updated accordingly; user-provided classes are unaffected. Generic processing components (`JobsQueue`, `Worker`, `WorkersPool`, `Schedulers::*`, `Jobs::Base`) stay in their original locations.
11
- - [Enhancement] Move processing strategies (`Karafka::Processing::Strategies::*` and `Karafka::Pro::Processing::Strategies::*`) under the `ConsumerGroups` namespace (internal). Prepares the processing layer for parallel `ShareGroups::Strategies` once KIP-932 lands.
12
- - [Enhancement] Move `Karafka::Processing::StrategySelector` and `Karafka::Pro::Processing::StrategySelector` under the `ConsumerGroups` namespace (internal). The `config.processing.strategy_selector` default is updated accordingly; user-provided selectors are unaffected.
13
- - [Enhancement] Move `Karafka::Connection::RebalanceManager` to `Karafka::Connection::ConsumerGroups::RebalanceManager` (internal). Prepares the connection layer for a parallel `ShareGroups` namespace once KIP-932 lands.
14
- - [Enhancement] Move the rebalance librdkafka callback to `Karafka::Instrumentation::Callbacks::ConsumerGroups::Rebalance` (internal). Published event names (`rebalance.*`) and payload shape are unchanged.
15
- - [Enhancement] Move `Karafka::Instrumentation::Callbacks::Error` and `Karafka::Instrumentation::Callbacks::Statistics` to `Karafka::Instrumentation::Callbacks::ConsumerGroups::Error` and `ConsumerGroups::Statistics` (internal). Completes the callbacks layer namespacing — all consumer-group-specific librdkafka callbacks now live under `Callbacks::ConsumerGroups`. Published event names and payload shape are unchanged.
16
- - [Enhancement] Namespace consumer-group-specific processing job classes under `Karafka::Processing::ConsumerGroups::Jobs` (OSS: `Consume`, `Eofed`, `Revoked`, `Shutdown`, `Idle`) and `Karafka::Pro::Processing::ConsumerGroups::Jobs` (Pro: `ConsumeNonBlocking`, `EofedNonBlocking`, `Periodic`, `PeriodicNonBlocking`, `RevokedNonBlocking`). Only `Jobs::Base` stays under `Karafka::Processing::Jobs` as the generic base class. Internal move only — no public API changes; prepares the processing layer for parallel `ShareGroups::Jobs` (KIP-932).
17
- - [Enhancement] Move `Karafka::Processing::JobsBuilder` to `Karafka::Processing::ConsumerGroups::JobsBuilder` and `Karafka::Pro::Processing::JobsBuilder` to `Karafka::Pro::Processing::ConsumerGroups::JobsBuilder` (internal). The jobs builder only creates consumer-group-specific jobs; prepares the processing layer for a parallel `ShareGroups::JobsBuilder` once KIP-932 lands.
18
- - [Enhancement] Nest consumer-group-specific processing config settings (`coordinator_class`, `errors_tracker_class`, `partitioner_class`, `strategy_selector`, `expansions_selector`, `executor_class`, `jobs_builder`) under `config.internal.processing.consumer_groups`. Shared settings (`jobs_queue_class`, `scheduler_class`, `worker_job_call_wrapper`) remain at the `config.internal.processing` level. Prepares the config structure for a parallel `config.internal.processing.share_groups` sub-namespace once KIP-932 lands.
19
- - [Enhancement] Move OSS consumer-group-specific routing features (`ActiveJob`, `DeadLetterQueue`, `Eofed`, `InlineInsights`, `ManualOffsetManagement`) from `Routing::Features` to `Routing::Features::ConsumerGroups` (internal). Agnostic features (`Declaratives`, `Deserializers`) remain at the `Routing::Features` level. Prepares the routing layer for a parallel `Routing::Features::ShareGroups` namespace once KIP-932 lands.
20
- - [Enhancement] Move Pro consumer-group-specific routing features (`ActiveJob`, `AdaptiveIterator`, `DeadLetterQueue`, `Delaying`, `DirectAssignments`, `InlineInsights`, `LongRunningJob`, `Multiplexing`, `NonBlockingJob`, `OffsetMetadata`, `ParallelSegments`, `Patterns`, `PeriodicJob`, `RecurringTasks`, `ScheduledMessages`, `Swarm`, `VirtualPartitions`) from `Pro::Routing::Features` to `Pro::Routing::Features::ConsumerGroups` (internal). Agnostic features (`Expiring`, `Filtering`, `Pausing`, `Throttling`) remain at the `Pro::Routing::Features` level.
21
- - [Enhancement] Introduce polymorphic `Routing::Topic#group` and `Routing::SubscriptionGroup#group` accessors (with `#consumer_group` kept as a backwards-compatible alias), expose `group_id` alongside `consumer_group_id` in `Routing::Topic#to_h`, emit parallel `group:` / `group_id:` keys alongside `consumer_group:` / `consumer_group_id:` in `rebalance.*` payloads, and emit parallel `group_id:` alongside `consumer_group_id:` in `error.occurred` and `statistics.emitted` payloads (these callbacks only carry the group id, not the group object). Prepares routing for additional group types (e.g. KIP-932 share groups); legacy keys remain and will be retired in Karafka 3.0 once share groups land.
4
+ - **[Feature]** Add `Karafka::Admin.read_partition_offsets` (and `Admin::Topics#read_partition_offsets`) exposing the `rd_kafka_ListOffsets` admin API to query partition offsets by spec (`:earliest`, `:latest`, `:max_timestamp`, or a timestamp in ms) without a consumer group. Accepts an optional `isolation_level:` keyword (pass `READ_COMMITTED` for the Last Stable Offset instead of the high-watermark, giving accurate lag on transactional topics).
5
+ - **[Feature]** Add `Karafka::Connection::Client#read_partition_offsets` (and `Connection::Proxy#read_partition_offsets`) exposing the batched `ListOffsets` query on a consumer's own connection, forwarding its `isolation.level`. Note that `:latest` resolves to the high watermark regardless of isolation level, so it includes uncommitted messages on topics with in-flight transactions.
6
+ - **[Feature]** Allow `Karafka::Admin` (and subsystems like `Admin::ConsumerGroups`, `Admin::Topics`) to operate on an external client via `Karafka::Admin.new(external_client: client)`. Reuses the caller's client (no per-call bootstrap); its lifecycle stays with its owner.
7
+ - **[Feature]** Add `Karafka::Admin::IsolationLevels` module with `READ_UNCOMMITTED` and `READ_COMMITTED` constants wrapping the underlying rdkafka integer constants.
8
+ - **[Feature]** Introduce standalone `Karafka::Declaratives` subsystem (`Declaratives::Topic`, `Declaratives::Repository`, `Declaratives::Builder`) decoupled from routing. Topics can be declared via `Karafka::App.declaratives.draw`; the existing `routing#config(...)` DSL keeps working as a backwards-compatible bridge.
22
9
  - **[Feature]** Add `Processing::WorkersPool` with dynamic thread pool scaling via `#scale`, `nil` sentinel-based worker exit for downscaling, and `worker.scaling.up`/`worker.scaling.down` instrumentation events.
10
+ - [Enhancement] Refresh watermark offsets and lags of long-paused partitions in `statistics.emitted` (Pro). Opt-in via `config.internal.statistics.consumer_groups.lag_compensation.interval` (ms, default `0` - disabled); partitions qualify after being paused for at least `lag_compensation.pause_age` (ms, min `5_000`, default `30_000`). Refreshed values are kept on resume until live statistics catch up, then dropped in bulk on the next rebalance.
11
+ - [Enhancement] Replace per-partition `query_watermark_offsets` calls with batched `list_offsets` in `Admin::Topics#read_watermark_offsets`, `Admin::ConsumerGroups#seek`, and `Pro::Iterator::TplBuilder#resolve_partitions_with_negative_offsets`, cutting N sequential roundtrips to a small constant and avoiding a dedicated admin client in the iterator path (Pro).
12
+ - [Enhancement] Add `stability_ttl` to `Kubernetes::LivenessListener` and `Pro::Swarm::LivenessListener` to detect consumers frozen in a single non-`"steady"` librdkafka `cgrp.join_state`. On breach, reports `stability_ttl_exceeded: true` (HTTP 500) / status code `4`; clears once the group returns to `"steady"`. Requires `statistics.interval.ms`; defaults to twice the max `max.poll.interval.ms` across active subscription groups.
13
+ - [Enhancement] Contain non-`StandardError` errors (`ScriptError`, `SystemStackError`, etc.) raised in the consumption flow through the normal retry/pause/DLQ flow instead of skipping the batch. Process-critical errors (`SystemExit`, `SignalException`, `NoMemoryError`) are recorded, keep the partition paused, and trigger a graceful shutdown via the auto-subscribed `Instrumentation::CriticalErrorsListener` instead of being retried or dispatched to the DLQ. Configurable via `config.internal.processing.critical_errors`.
14
+ - [Enhancement] Introduce polymorphic `Routing::Topic#group` and `Routing::SubscriptionGroup#group` accessors (`#consumer_group` kept as a backwards-compatible alias), expose `group_id` in `Routing::Topic#to_h`, and emit parallel `group`/`group_id` keys alongside the legacy `consumer_group`/`consumer_group_id` keys in `rebalance.*`, `error.occurred`, and `statistics.emitted` payloads. Prepares routing for KIP-932 share groups; legacy keys remain until Karafka 3.0.
15
+ - [Enhancement] Add `Pro::Processing::ConsumerGroups::Filters::Actions` as the single source of truth for filter post-execution actions (`Actions.skip`/`Actions.pause`/`Actions.seek` value methods, the `ALL` list, and `#skip?`/`#pause?`/`#seek?` predicates mixed into `Filters::Base` and `Coordinators::FiltersApplier`). Returned values remain the same plain symbols, so existing filters keep working (Pro).
16
+ - [Enhancement] Make the statistics decorator used by `Instrumentation::Callbacks::ConsumerGroups::Statistics` configurable via `config.internal.statistics.consumer_groups.decorator_class` instead of hardcoding `Karafka::Core::Monitoring::StatisticsDecorator`.
17
+ - [Enhancement] Declare recurring tasks and scheduled messages internal topics via the standalone `Karafka::App.declaratives.draw` DSL instead of the routing `config(...)` bridge; the resulting declarations are unchanged (Pro).
18
+ - [Enhancement] CLI topic commands (`create`, `delete`, `reset`, `repartition`, `align`, `migrate`, `plan`) now read from `Karafka::App.declaratives.topics` instead of walking the routing tree, so topics declared via `declaratives.draw` are managed without a routing entry.
23
19
  - [Enhancement] Add per-partition generation tracking to `AssignmentsTracker` to distinguish first-time assignments from reassignments.
24
20
  - [Enhancement] Make liveness listeners fiber-safe.
25
- - [Fix] Include orphaned node detection in Pro swarm liveness listener.
26
- - [Fix] Report liveness on `connection.listener.before_fetch_loop` so nodes send an initial healthy report before the first consumption.
27
- - [Fix] Fire liveness events during `wait_pinging` so nodes continue reporting health status during shutdown with active LRJ jobs.
21
+ - [Enhancement] Bump swarm supervisor `SHUTDOWN_GRACE_PERIOD` from 1s to 15s to give forked nodes enough time to finish post-`shutdown_timeout` cleanup before forceful termination.
22
+ - [Enhancement] Move consumer-group-specific `Processing` components (`Coordinator`, `CoordinatorsBuffer`, `Executor`, `ExecutorsBuffer`, `Partitioner`, `ExpansionsSelector`, `InlineInsights`) and their Pro equivalents under the `ConsumerGroups` namespace (internal). Related config defaults are updated; user-provided classes are unaffected.
23
+ - [Enhancement] Move processing strategies (`Processing::Strategies::*` and `Pro::Processing::Strategies::*`) under the `ConsumerGroups` namespace (internal), preparing for parallel `ShareGroups::Strategies` (KIP-932).
24
+ - [Enhancement] Move `Processing::StrategySelector` (OSS and Pro) under the `ConsumerGroups` namespace (internal); the `config.processing.strategy_selector` default is updated, user selectors unaffected.
25
+ - [Enhancement] Move `Karafka::Connection::RebalanceManager` to `Connection::ConsumerGroups::RebalanceManager` (internal).
26
+ - [Enhancement] Move the rebalance librdkafka callback to `Instrumentation::Callbacks::ConsumerGroups::Rebalance` (internal); event names and payloads unchanged.
27
+ - [Enhancement] Move `Instrumentation::Callbacks::Error` and `Callbacks::Statistics` under `Callbacks::ConsumerGroups` (internal), completing the callbacks-layer namespacing; event names and payloads unchanged.
28
+ - [Enhancement] Namespace consumer-group-specific processing job classes under `Processing::ConsumerGroups::Jobs` (OSS) and `Pro::Processing::ConsumerGroups::Jobs` (Pro); only `Jobs::Base` stays generic. Internal move, no public API changes.
29
+ - [Enhancement] Move `Processing::JobsBuilder` (OSS and Pro) under the `ConsumerGroups` namespace (internal).
30
+ - [Enhancement] Nest consumer-group-specific processing config settings (`coordinator_class`, `errors_tracker_class`, `partitioner_class`, `strategy_selector`, `expansions_selector`, `executor_class`, `jobs_builder`) under `config.internal.processing.consumer_groups`; shared settings stay at `config.internal.processing`.
31
+ - [Enhancement] Move OSS consumer-group-specific routing features (`ActiveJob`, `DeadLetterQueue`, `Eofed`, `InlineInsights`, `ManualOffsetManagement`) under `Routing::Features::ConsumerGroups` (internal); agnostic features stay put.
32
+ - [Enhancement] Move Pro consumer-group-specific routing features under `Pro::Routing::Features::ConsumerGroups` (internal); agnostic features (`Expiring`, `Filtering`, `Pausing`, `Throttling`) stay put.
33
+ - [Change] Require `karafka-rdkafka` `>= 0.28.0`, which exposes `Rdkafka::Consumer#list_offsets` and rebuilds `#lag` on top of it, so lag reads issue a single batched end-offsets query instead of one watermark roundtrip per partition.
34
+ - [Change] Require `karafka-rdkafka` `>= 0.27.1` for the `poll_batch`/`poll_batch_nb` fix that discarded topic/partition/offset context from `e.details`, causing `TopicNotFoundError` crashes on `partition_eof`.
35
+ - [Change] Remove the public `custom_kafka` reader from `Karafka::Admin` (internal collaboration detail, unused by any public API; custom kafka settings are provided at construction via `Karafka::Admin.new(kafka: ...)`).
36
+ - [Refactor] Remove the unused `@mutex` from `Pro::Connection::Manager` (dead since #1851 replaced lock-based `@changes` eviction with key preloading; the lock-free threading model is now documented) (Pro).
37
+ - [Maintenance] Split declarative topic configuration from routing in the integration suite: add a `draw_topics` spec helper wrapping `Karafka::App.declaratives.draw`, source spec topic creation from the declaratives repository, and migrate general integration specs to declare partitions/config via `draw_topics`.
38
+ - [Maintenance] Replace manual per-version `Warning[:performance]`/`Warning[:deprecated]` spec setup with a dynamic `Warning.categories`-based approach that enables all non-experimental warning categories automatically.
28
39
  - [Maintenance] Use namespaced topic naming format in all integration specs for consistent traceability.
29
- - [Fix] Fix `DataCollector::SPEC_HASH` producing non-deterministic hashes for pristine and poro specs by passing the original spec path via `KARAFKA_SPEC_PATH` env var.
30
- - [Fix] Fix swarm supervisor leaking reader pipe file descriptors on node restarts by closing the old reader before creating a new pipe in `Node#start`.
31
40
  - [Maintenance] Add `bin/tests_topics_hashes` script for looking up spec files by their topic name hash prefix.
32
- - [Change] Require `karafka-rdkafka` `>=` `0.27.1` to pick up the fix for `poll_batch` and `poll_batch_nb` raising `RdkafkaError` with only the integer error code, which discarded topic/partition/offset context from `e.details` and caused `partition_eof` handling to call `@buffer.eof(nil, nil)`, resulting in a `TopicNotFoundError` crash.
33
- - [Fix] Raise `InvalidLicenseTokenError` when a manually-defined `Karafka::License` module is missing required methods (`#token` or `#version`) instead of silently skipping pro component loading, which previously caused confusing `NameError` exceptions later in the boot process.
34
- - [Enhancement] Bump swarm supervisor `SHUTDOWN_GRACE_PERIOD` from 1s to 15s to give forked nodes enough time to finish post-`shutdown_timeout` cleanup (at_exit handlers, librdkafka finalization, connection pool close) before the supervisor forcefully terminates them, especially on CI where `sleep` granularity and `waitpid` cost stretch each supervision loop iteration.
35
- - [Maintenance] Fix flaky `pro/admin/recovery/coordinator_for_spec.rb` by warming up the `__consumer_offsets` internal topic with a produce + `seek_consumer_group` and retrying the first `Recovery.coordinator_for` call with exponential backoff on `MetadataError`.
41
+ - [Maintenance] Fix flaky `pro/admin/recovery/coordinator_for_spec.rb` by warming up the `__consumer_offsets` topic and retrying the first `Recovery.coordinator_for` call with exponential backoff on `MetadataError`.
42
+ - [Fix] Compare recurring task schedule versions with `Gem::Version` instead of as strings, so multi-segment upgrades like `1.9.0` `1.10.0` are no longer misread as downgrades and rejected with `IncompatibleScheduleError` (Pro).
43
+ - [Fix] Fix dynamic multiplexing `scale_delay` being applied globally instead of per subscription-group family (`Pro::Connection::Manager#stable?` memoized the first family's value for all); it is now read per family on every check (Pro).
44
+ - [Fix] Make `Routing::Topics#<<` copy-on-write so a topic discovered at runtime by a pattern subscription can no longer be observed mid-append by a concurrent reader (e.g. `Router#find_by` from a `Pro::Iterator` or `Admin` call on another thread).
45
+ - [Fix] Bound `Instrumentation::AssignmentsTracker`'s `@generations` map (`GENERATIONS_TOPICS_LIMIT`, LRU eviction) so it no longer grows for the whole process lifetime under regex pattern subscriptions; static topologies are unaffected.
46
+ - [Fix] Derive the filtering pause timeout only from filters that actually want to pause, so a coexisting `:seek` filter reporting a `0` timeout no longer collapses a `:pause` to `0` and busy-spins (Pro).
47
+ - [Fix] Clamp scheduled message CreateTime to the wall clock in the loaded heuristic, so a single future-dated message can no longer be taken as proof of catch-up and cause double dispatch of not-yet-loaded cancellations (Pro).
48
+ - [Fix] Reset `Pro::Iterator#each` EOF/stop tracking in an `ensure`, so breaking out of the yielded block no longer leaves `done?` immediately true and silently drops a fresh backlog on reuse (Pro).
49
+ - [Fix] Fix the `parallel_segments` CLI commands (`distribute`, `collapse`, `reset`) silently skipping groups when more than one was requested via `--groups` (the matched group was deleted from the array being iterated); all requested groups are now processed (Pro).
50
+ - [Fix] Evict a partition's samples from `Pro::Instrumentation::PerformanceTracker` on revoke and scope samples by subscription group id, fixing unbounded growth and cross-group interference. **Breaking (internal API):** `processing_time_p95` now takes the subscription group id first (`processing_time_p95(group_id, topic, partition)`) (Pro).
51
+ - [Fix] Fall back to the current offset metadata (instead of raising `KeyError`) in Virtual Partitions `VirtualOffsetManager#markable` under the `:exact` strategy when the lowest-offset virtual-partition group is left unmarked (Pro).
52
+ - [Fix] Leave tombstone records (key with a `nil` payload) untouched on produce and consume instead of crashing in `cipher.encrypt`/`decrypt`, so they remain valid tombstones for log compaction (Pro).
53
+ - [Fix] Recompute the `Pro::Processing::JobsQueue#clear` async-locking fast-path flag from the remaining groups' locks instead of forcing it off globally, so another subscription group's active `lock_async` locks are no longer ignored (Pro).
54
+ - [Fix] Reset the per-partition retry attempt counter on revocation, so a message reclaimed after a rebalance is no longer treated as having exhausted its retries and dispatched to the DLQ early.
55
+ - [Fix] Reset ActiveJob `CurrentAttributes` in an `ensure`, so a failed job's attributes no longer leak into the next job on the same worker.
56
+ - [Fix] Return `false` from `#mark_as_consumed`, `#mark_as_consumed!`, and `#commit_offsets!` when the operation fails because the partition was lost (previously could return `true`).
57
+ - [Fix] Reset `seek_offset` only after a `#seek` succeeds, so a raising seek (e.g. an unresolvable time-based offset) no longer pauses without seeking back and skips the rest of the batch.
58
+ - [Fix] Skip DLQ dispatch when the partition was revoked mid-job in the ActiveJob + DLQ + long-running job strategies (matching the non-AJ LRJ strategies), so the new owner handles it instead of producing a duplicate (Pro).
59
+ - [Fix] Advance the in-memory `seek_offset` only after a transactional DLQ dispatch succeeds, so an aborted dispatch transaction with `mark_after_dispatch: false` no longer skips the broken message (Pro).
60
+ - [Fix] Report ownership truthfully from Virtual Partitions `#mark_as_consumed`/`#mark_as_consumed!` when there is no real offset to materialize yet (previously inverted) (Pro).
61
+ - [Fix] Stop reverting recurring task commands consumed during the boot replay phase, which previously persisted the reverted state and lost the command permanently (Pro).
62
+ - [Fix] Always precede Virtual Partitions DLQ `:dispatch`/`:skip` decisions with a collapsed retry, so they run on the linear deterministic flow instead of an arbitrary virtual-partition subset that could lose messages or dispatch the wrong one (Pro).
63
+ - [Fix] Compare scheduled messages schema versions as `Gem::Version` instead of strings, fixing mis-evaluation once a version segment reaches two digits (Pro).
64
+ - [Fix] Fix `Karafka::Admin.read_topic` with a `Time` start offset beyond the last message returning the newest messages instead of none.
65
+ - [Fix] Prevent silent worker thread death draining the workers pool: worker continuation is now an explicit framework decision (only a closed queue or downscale sentinel stops a worker), so a user `Consumer#wrap` returning a falsy value no longer kills the thread.
66
+ - [Fix] Track `Pro::Iterator` EOF and explicit stops per topic-partition instead of globally, so a partition receiving new data mid-iteration no longer exhausts the EOF budget and terminates `#each` while others still have backlog; `#each` also resets `#stop` on finish so the iterator can be reused (Pro).
67
+ - [Fix] Include orphaned node detection in the Pro swarm liveness listener.
68
+ - [Fix] Report liveness on `connection.listener.before_fetch_loop` so nodes send an initial healthy report before the first consumption.
69
+ - [Fix] Fire liveness events during `wait_pinging` so nodes keep reporting health during shutdown with active LRJ jobs.
70
+ - [Fix] Fix `DataCollector::SPEC_HASH` producing non-deterministic hashes for pristine and poro specs by passing the original spec path via the `KARAFKA_SPEC_PATH` env var.
71
+ - [Fix] Fix the swarm supervisor leaking reader pipe file descriptors on node restarts by closing the old reader before creating a new pipe in `Node#start`.
72
+ - [Fix] Raise `InvalidLicenseTokenError` when a manually-defined `Karafka::License` module is missing `#token` or `#version` instead of silently skipping Pro loading and raising a confusing `NameError` later in boot.
36
73
 
37
74
  ## 2.5.9 (2026-03-30)
38
75
  - [Enhancement] Validate that `statistics.interval.ms` is not zero when dynamic multiplexing is enabled (Pro).
data/certs/expired.txt CHANGED
@@ -19,6 +19,7 @@
19
19
  39aeae710122bf14729a05f24f5bd702d2a1127e5c7fb9bd90de0e20890575dc
20
20
  3ada575caaf0b8bdeca0686a93074de9ed830751e6f46251849475f70e84e408
21
21
  4367e57ca36a4b447f23745d76611514df61b56611225be4c8f9a90560bbace9
22
+ 4611be91c816b50c54e7e4ec422e02363bc5450f9107a35d7e915d949ccf7bdb
22
23
  47380207ca3041b14c7d4c81a69f820852069ecab4d80a068d39133f61a6e641
23
24
  4d49b497ece81604358afc8e9adc7d1163995c4c08446bcd5c0bbfe3d7ebc1e7
24
25
  4d97c95c46e51105705964aecbfa5219120295e7d0a172f5c098d12c3a5cbf7e
@@ -62,6 +63,7 @@ bf6c5c58b02fa5e7c7dc845213ad943c5b6613f12ac6012be00b1484bb85aa04
62
63
  c011c3d168a159c135ef35bf55121edaf1a4cc94f663a1f461595776b0313160
63
64
  c311cb6cfb38a8b2e83b3080c1f87444a52f3f645be8337559a123aaacf1344a
64
65
  c87222a94f98c3a2191dda9254bd6ed031fd8ca190f75b40c67a0fcd4b56f795
66
+ c9a5cc3f4c0fc7cb8784978d1f5185340ab585baf3b5d94300a29b212310871b
65
67
  ca53af70cd7e67abbb9dbf0a8da6788a9b2192aa3a5a1dd8720aaa68a2511722
66
68
  d02da0cbd2c1d83432a2cee7984dd311249692373554002d1d543dd5007f6a58
67
69
  d13295e597120b88bf4c4f36de63d0aa3e5a68e3578c09a2e026bd1f6aaaf04f
@@ -37,6 +37,7 @@ en:
37
37
  internal.processing.jobs_queue_class_format: cannot be nil
38
38
  internal.processing.scheduler_class_format: cannot be nil
39
39
  internal.processing.worker_job_call_wrapper_format: 'needs to be false or respond to #wrap'
40
+ internal.processing.critical_errors_format: 'needs to be an array of Exception subclasses'
40
41
  internal.processing.consumer_groups.jobs_builder_format: cannot be nil
41
42
  internal.processing.consumer_groups.coordinator_class_format: cannot be nil
42
43
  internal.processing.consumer_groups.errors_tracker_class_format: 'needs to be nil or a class'
@@ -45,6 +46,10 @@ en:
45
46
  internal.processing.consumer_groups.expansions_selector_format: cannot be nil
46
47
  internal.processing.consumer_groups.executor_class_format: cannot be nil
47
48
 
49
+ internal.statistics.consumer_groups.decorator_class_format: cannot be nil
50
+ internal.statistics.consumer_groups.lag_compensation.interval_format: needs to be an Integer greater or equal to 0
51
+ internal.statistics.consumer_groups.lag_compensation.pause_age_format: needs to be an Integer greater or equal to 5000
52
+
48
53
  internal.active_job.dispatcher_format: cannot be nil
49
54
  internal.active_job.job_options_contract_format: cannot be nil
50
55
  internal.active_job.consumer_class_format: cannot be nil
data/karafka.gemspec CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
  DESC
23
23
 
24
24
  spec.add_dependency "karafka-core", ">= 2.6.0", "< 2.7.0"
25
- spec.add_dependency "karafka-rdkafka", ">= 0.27.2"
25
+ spec.add_dependency "karafka-rdkafka", ">= 0.28.0"
26
26
  spec.add_dependency "waterdrop", ">= 2.10.1", "< 3.0.0"
27
27
  spec.add_dependency "zeitwerk", "~> 2.3"
28
28
 
@@ -20,7 +20,7 @@ module ActiveJob
20
20
  # - Other Rails versions: Inherit from AbstractAdapter (normal behavior)
21
21
  # - No Rails: Inherit from Object (standalone ActiveJob usage)
22
22
  #
23
- # @see https://github.com/sidekiq/sidekiq/issues/6746 Similar issue in Sidekiq
23
+ # See https://github.com/sidekiq/sidekiq/issues/6746 Similar issue in Sidekiq
24
24
  base = if defined?(Rails::VERSION)
25
25
  ((Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR < 2) ? Object : AbstractAdapter)
26
26
  else
@@ -26,7 +26,7 @@ module Karafka
26
26
  end
27
27
 
28
28
  yield(job)
29
-
29
+ ensure
30
30
  resetable.each(&:reset)
31
31
  end
32
32
  end
@@ -5,11 +5,13 @@ require_relative "current_attributes/job_wrapper"
5
5
  require_relative "current_attributes/loading"
6
6
  require_relative "current_attributes/persistence"
7
7
 
8
- # This code is based on Sidekiqs approach to persisting current attributes
9
- # @see https://github.com/sidekiq/sidekiq/blob/main/lib/sidekiq/middleware/current_attributes.rb
10
8
  module Karafka
11
9
  module ActiveJob
12
10
  # Module that allows to persist current attributes on Karafka jobs
11
+ #
12
+ # This code is based on Sidekiqs approach to persisting current attributes
13
+ #
14
+ # @see https://github.com/sidekiq/sidekiq/blob/main/lib/sidekiq/middleware/current_attributes.rb
13
15
  module CurrentAttributes
14
16
  # Allows for persistence of given current attributes via AJ + Karafka
15
17
  #
@@ -8,8 +8,7 @@ module Karafka
8
8
  deserializer: %i[internal active_job deserializer]
9
9
  )
10
10
 
11
- # Defaults for dispatching
12
- # The can be updated by using `#karafka_options` on the job
11
+ # Defaults for dispatching. They can be updated by using `#karafka_options` on the job
13
12
  DEFAULTS = {
14
13
  dispatch_method: :produce_async,
15
14
  dispatch_many_method: :produce_many_async
@@ -110,7 +110,7 @@ module Karafka
110
110
  if partitions_with_offsets.is_a?(Hash)
111
111
  tpl_base[topic] = partitions_with_offsets
112
112
  else
113
- topic_info = Topics.new(kafka: @custom_kafka).info(topic)
113
+ topic_info = topics_admin.info(topic)
114
114
  topic_info[:partition_count].times do |partition|
115
115
  tpl_base[topic][partition] = partitions_with_offsets
116
116
  end
@@ -358,7 +358,9 @@ module Karafka
358
358
  sleep(0.1)
359
359
 
360
360
  # Unsubscribe - this will trigger the second rebalance when the consumer closes
361
- # The ensure block in with_consumer will handle the unsubscribe and close
361
+ # The ensure block in with_consumer will handle the unsubscribe and close for the
362
+ # dedicated consumer created here. This operation subscribes and must never run on
363
+ # an external client as nothing would restore its subscription
362
364
  end
363
365
  end
364
366
 
@@ -380,6 +382,10 @@ module Karafka
380
382
  #
381
383
  # @note This lag reporting is for committed lags and is "Kafka-centric", meaning that this
382
384
  # represents lags from Kafka perspective and not the consumer. They may differ.
385
+ #
386
+ # @note When this instance operates on an external client, every queried group runs
387
+ # through that single consumer identity, so query it only about the external client's
388
+ # own group.
383
389
  def read_lags_with_offsets(groups_with_topics = {}, active_topics_only: true)
384
390
  # We first fetch all the topics with partitions count that exist in the cluster so we
385
391
  # do not query for topics that do not exist and so we can get partitions count for all
@@ -84,6 +84,8 @@ module Karafka
84
84
  # 2. As a plan result object when called with topic and plan parameters
85
85
  #
86
86
  # @param kafka [Hash] custom kafka configuration for admin operations (optional)
87
+ # @param external_client [Object, nil] external client for admin operations (optional)
88
+ # @see Karafka::Admin#initialize
87
89
  # @param topic [String] topic name (for plan result)
88
90
  # @param current_replication_factor [Integer] current replication factor (for plan result)
89
91
  # @param target_replication_factor [Integer] target replication factor (for plan result)
@@ -91,13 +93,14 @@ module Karafka
91
93
  # @param cluster_info [Hash] broker information (for plan result)
92
94
  def initialize(
93
95
  kafka: nil,
96
+ external_client: nil,
94
97
  topic: nil,
95
98
  current_replication_factor: nil,
96
99
  target_replication_factor: nil,
97
100
  partitions_assignment: nil,
98
101
  cluster_info: nil
99
102
  )
100
- super(kafka: kafka || {})
103
+ super(kafka: kafka || {}, external_client: external_client)
101
104
 
102
105
  # If topic is provided, this is a plan result object
103
106
  return unless topic
@@ -293,7 +296,7 @@ module Karafka
293
296
  # @param topic [String] name of the topic
294
297
  # @return [Hash] topic information with partitions metadata
295
298
  def fetch_topic_info(topic)
296
- Topics.new(kafka: @custom_kafka).info(topic)
299
+ topics_admin.info(topic)
297
300
  end
298
301
 
299
302
  # Fetches cluster broker information from Kafka metadata
@@ -464,7 +467,7 @@ module Karafka
464
467
  end
465
468
 
466
469
  # Builds the kafka-reassign-partitions.sh --generate command that asks Kafka to propose
467
- # its own reassignment plan. This is optional you can compare Kafka's suggestion against
470
+ # its own reassignment plan. This is optional - you can compare Kafka's suggestion against
468
471
  # the plan Karafka already computed, or skip this step and go straight to --execute.
469
472
  # @return [String] command template with placeholders for broker addresses and IDs
470
473
  def build_generate_command
@@ -68,7 +68,8 @@ module Karafka
68
68
  # @param count [Integer] how many messages we want to get at most
69
69
  # @param start_offset [Integer, Time] offset from which we should start. If -1 is provided
70
70
  # (default) we will start from the latest offset. If time is provided, the appropriate
71
- # offset will be resolved. If negative beyond -1 is provided, we move backwards more.
71
+ # offset will be resolved. A time beyond the last message yields no messages. If
72
+ # negative beyond -1 is provided, we move backwards more.
72
73
  # @param settings [Hash] kafka extra settings (optional)
73
74
  #
74
75
  # @return [Array<Karafka::Messages::Message>] array with messages
@@ -76,6 +77,7 @@ module Karafka
76
77
  messages = []
77
78
  tpl = Rdkafka::Consumer::TopicPartitionList.new
78
79
  low_offset, high_offset = nil
80
+ time_based = start_offset.is_a?(Time)
79
81
 
80
82
  with_consumer(settings) do |consumer|
81
83
  # Convert the time offset (if needed)
@@ -83,9 +85,20 @@ module Karafka
83
85
 
84
86
  low_offset, high_offset = consumer.query_watermark_offsets(name, partition)
85
87
 
86
- # Select offset dynamically if -1 or less and move backwards with the negative
87
- # offset, allowing to start from N messages back from high-watermark
88
- start_offset = high_offset - count - start_offset.abs + 1 if start_offset.negative?
88
+ if start_offset.negative?
89
+ start_offset = if time_based
90
+ # A negative result of time resolution means there is no message at or after the
91
+ # requested time. It must not fall into the numeric relative form below (which
92
+ # would return the newest messages, all older than requested): starting at the
93
+ # high watermark yields the correct empty result
94
+ high_offset
95
+ else
96
+ # Select offset dynamically if -1 or less and move backwards with the negative
97
+ # offset, allowing to start from N messages back from high-watermark
98
+ high_offset - count - start_offset.abs + 1
99
+ end
100
+ end
101
+
89
102
  start_offset = low_offset if start_offset.negative?
90
103
 
91
104
  # Build the requested range - since first element is on the start offset we need to
@@ -264,8 +277,8 @@ module Karafka
264
277
  # `READ_COMMITTED` consumer will never see those messages, so lag calculated from the
265
278
  # high-watermark is overstated on transactionally-produced topics. Passing
266
279
  # `isolation_level: Karafka::Admin::IsolationLevels::READ_COMMITTED` here
267
- # returns the Last Stable Offset (LSO) the highest offset a `READ_COMMITTED` consumer
268
- # would actually reach giving accurate lag figures.
280
+ # returns the Last Stable Offset (LSO) - the highest offset a `READ_COMMITTED` consumer
281
+ # would actually reach - giving accurate lag figures.
269
282
  #
270
283
  # - `:max_timestamp` spec: returns the offset of the message with the highest timestamp
271
284
  # in the partition. Not available via watermarks.
@@ -297,12 +310,19 @@ module Karafka
297
310
  #
298
311
  # @raise [Rdkafka::RdkafkaError] on per-partition errors or connection issues
299
312
  #
313
+ # @note The specs must be passed as an explicit hash (in curly braces). Ruby parses a
314
+ # brace-less trailing hash as keyword arguments, and since this method takes an
315
+ # `isolation_level:` keyword, such a call raises an `ArgumentError` about a missing
316
+ # positional argument.
317
+ #
300
318
  # @example Query earliest offset for partition 0 and latest for partition 1
301
319
  # Karafka::Admin::Topics.read_partition_offsets(
302
- # 'events' => [
303
- # { partition: 0, offset: :earliest },
304
- # { partition: 1, offset: :latest }
305
- # ]
320
+ # {
321
+ # 'events' => [
322
+ # { partition: 0, offset: :earliest },
323
+ # { partition: 1, offset: :latest }
324
+ # ]
325
+ # }
306
326
  # )
307
327
  # # => [
308
328
  # # { topic: 'events', partition: 0, offset: 0, timestamp: -1, leader_epoch: nil },
@@ -311,13 +331,13 @@ module Karafka
311
331
  #
312
332
  # @example Get LSO (Last Stable Offset) for accurate lag on transactional topics
313
333
  # Karafka::Admin::Topics.read_partition_offsets(
314
- # 'events' => [{ partition: 0, offset: :latest }],
334
+ # { 'events' => [{ partition: 0, offset: :latest }] },
315
335
  # isolation_level: Karafka::Admin::IsolationLevels::READ_COMMITTED
316
336
  # )
317
337
  #
318
338
  # @example Find offset at a specific point in time
319
339
  # Karafka::Admin::Topics.read_partition_offsets(
320
- # 'events' => [{ partition: 0, offset: 1_700_000_000_000 }]
340
+ # { 'events' => [{ partition: 0, offset: 1_700_000_000_000 }] }
321
341
  # )
322
342
  def read_partition_offsets(topic_partition_offsets, isolation_level: nil)
323
343
  with_admin do |admin|