karafka 2.5.10.rc1 → 2.6.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -2
  3. data/config/locales/errors.yml +14 -7
  4. data/karafka.gemspec +3 -3
  5. data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -2
  6. data/lib/karafka/active_job/job_extensions.rb +1 -2
  7. data/lib/karafka/admin/configs/resource.rb +1 -2
  8. data/lib/karafka/admin/consumer_groups.rb +109 -98
  9. data/lib/karafka/admin/isolation_levels.rb +22 -0
  10. data/lib/karafka/admin/topics.rb +103 -8
  11. data/lib/karafka/admin.rb +59 -31
  12. data/lib/karafka/app.rb +16 -5
  13. data/lib/karafka/base_consumer.rb +2 -2
  14. data/lib/karafka/cli/contracts/server.rb +4 -4
  15. data/lib/karafka/cli/info.rb +1 -1
  16. data/lib/karafka/cli/topics/base.rb +10 -18
  17. data/lib/karafka/cli/topics/repartition.rb +1 -1
  18. data/lib/karafka/connection/client.rb +33 -8
  19. data/lib/karafka/connection/consumer_groups/rebalance_manager.rb +120 -0
  20. data/lib/karafka/connection/listener.rb +6 -6
  21. data/lib/karafka/connection/listeners_batch.rb +1 -1
  22. data/lib/karafka/connection/mode.rb +1 -2
  23. data/lib/karafka/connection/raw_messages_buffer.rb +0 -5
  24. data/lib/karafka/declaratives/builder.rb +65 -0
  25. data/lib/karafka/declaratives/contracts/topic.rb +28 -0
  26. data/lib/karafka/declaratives/repository.rb +52 -0
  27. data/lib/karafka/declaratives/topic.rb +100 -0
  28. data/lib/karafka/declaratives.rb +9 -0
  29. data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +56 -0
  30. data/lib/karafka/instrumentation/callbacks/consumer_groups/rebalance.rb +93 -0
  31. data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +59 -0
  32. data/lib/karafka/instrumentation/logger_listener.rb +8 -9
  33. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +13 -14
  34. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +7 -8
  35. data/lib/karafka/instrumentation/vendors/kubernetes/base_listener.rb +7 -3
  36. data/lib/karafka/licenser.rb +16 -3
  37. data/lib/karafka/pro/active_job/consumer.rb +1 -2
  38. data/lib/karafka/pro/active_job/dispatcher.rb +1 -2
  39. data/lib/karafka/pro/admin/recovery.rb +19 -19
  40. data/lib/karafka/pro/base_consumer.rb +3 -3
  41. data/lib/karafka/pro/cli/contracts/server.rb +5 -5
  42. data/lib/karafka/pro/cli/parallel_segments/base.rb +7 -7
  43. data/lib/karafka/pro/cli/parallel_segments/collapse.rb +4 -4
  44. data/lib/karafka/pro/cli/parallel_segments/distribute.rb +6 -6
  45. data/lib/karafka/pro/iterator/tpl_builder.rb +38 -18
  46. data/lib/karafka/pro/loader.rb +13 -12
  47. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +84 -0
  48. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +97 -0
  49. data/lib/karafka/pro/processing/consumer_groups/collapser.rb +84 -0
  50. data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +202 -0
  51. data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +124 -0
  52. data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +157 -0
  53. data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +212 -0
  54. data/lib/karafka/pro/processing/{filters/expirer.rb → consumer_groups/executor.rb} +17 -31
  55. data/lib/karafka/pro/processing/{jobs/periodic.rb → consumer_groups/expansions_selector.rb} +18 -21
  56. data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +103 -0
  57. data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +92 -0
  58. data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +78 -0
  59. data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +99 -0
  60. data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +106 -0
  61. data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +79 -0
  62. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/consume_non_blocking.rb +21 -17
  63. data/lib/karafka/pro/processing/{virtual_partitions/distributors/consistent.rb → consumer_groups/jobs/eofed_non_blocking.rb} +16 -14
  64. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +64 -0
  65. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/periodic_non_blocking.rb +16 -11
  66. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/revoked_non_blocking.rb +19 -15
  67. data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +95 -0
  68. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +66 -0
  69. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +154 -0
  70. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +68 -0
  71. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +102 -0
  72. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +115 -0
  73. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +96 -0
  74. data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +98 -0
  75. data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +90 -0
  76. data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +154 -0
  77. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +93 -0
  78. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +99 -0
  79. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +92 -0
  80. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +90 -0
  81. data/lib/karafka/pro/processing/{strategies/aj/dlq_ftr_lrj_mom.rb → consumer_groups/strategies/aj/dlq_lrj_mom.rb} +37 -39
  82. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +90 -0
  83. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +84 -0
  84. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +89 -0
  85. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_lrj_mom.rb +20 -15
  86. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +91 -0
  87. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_mom.rb +20 -15
  88. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +80 -0
  89. data/lib/karafka/pro/processing/{strategies/mom/default.rb → consumer_groups/strategies/aj/lrj_mom.rb} +18 -22
  90. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +106 -0
  91. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +58 -0
  92. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +74 -0
  93. data/lib/karafka/pro/processing/{strategies/lrj/vp.rb → consumer_groups/strategies/base.rb} +9 -14
  94. data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +421 -0
  95. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +285 -0
  96. data/lib/karafka/pro/processing/{strategies/dlq/lrj.rb → consumer_groups/strategies/dlq/ftr.rb} +30 -29
  97. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +95 -0
  98. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +97 -0
  99. data/lib/karafka/pro/processing/{executor.rb → consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb} +26 -15
  100. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +63 -0
  101. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +97 -0
  102. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +63 -0
  103. data/lib/karafka/pro/{routing/features/patterns/patterns.rb → processing/consumer_groups/strategies/dlq/ftr_vp.rb} +22 -12
  104. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +83 -0
  105. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +100 -0
  106. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/dlq/lrj_mom_vp.rb +18 -13
  107. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +61 -0
  108. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +96 -0
  109. data/lib/karafka/pro/processing/{strategies/lrj → consumer_groups/strategies/dlq}/mom_vp.rb +19 -15
  110. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +62 -0
  111. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +146 -0
  112. data/lib/karafka/pro/processing/{strategies/mom/ftr.rb → consumer_groups/strategies/ftr/vp.rb} +20 -28
  113. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +119 -0
  114. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +94 -0
  115. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +92 -0
  116. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +62 -0
  117. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +61 -0
  118. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +101 -0
  119. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +60 -0
  120. data/lib/karafka/pro/processing/{strategies/mom → consumer_groups/strategies/lrj}/vp.rb +18 -12
  121. data/lib/karafka/pro/processing/{strategies/aj/mom_vp.rb → consumer_groups/strategies/mom/default.rb} +22 -23
  122. data/lib/karafka/pro/processing/{strategies/aj/ftr_mom_vp.rb → consumer_groups/strategies/mom/ftr.rb} +28 -28
  123. data/lib/karafka/pro/processing/{virtual_partitions/distributors/base.rb → consumer_groups/strategies/mom/ftr_vp.rb} +19 -14
  124. data/lib/karafka/pro/processing/{strategies/aj/mom.rb → consumer_groups/strategies/mom/vp.rb} +16 -12
  125. data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +197 -0
  126. data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +106 -0
  127. data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +73 -0
  128. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +82 -0
  129. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +59 -0
  130. data/lib/karafka/pro/processing/{strategies/dlq/ftr.rb → consumer_groups/virtual_partitions/distributors/consistent.rb} +18 -33
  131. data/lib/karafka/pro/processing/filters/base.rb +3 -61
  132. data/lib/karafka/pro/processing/partitioner.rb +2 -57
  133. data/lib/karafka/pro/processing/schedulers/base.rb +10 -6
  134. data/lib/karafka/pro/processing/schedulers/default.rb +6 -5
  135. data/lib/karafka/pro/recurring_tasks/executor.rb +1 -2
  136. data/lib/karafka/pro/routing/features/{active_job → consumer_groups/active_job}/builder.rb +20 -18
  137. data/lib/karafka/pro/routing/features/{inline_insights/config.rb → consumer_groups/active_job.rb} +5 -9
  138. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/config.rb +53 -0
  139. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/contracts/topic.rb +91 -0
  140. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/topic.rb +90 -0
  141. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator.rb +50 -0
  142. data/lib/karafka/pro/routing/features/{patterns/contracts/consumer_group.rb → consumer_groups/dead_letter_queue/contracts/topic.rb} +25 -30
  143. data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue/topic.rb +70 -0
  144. data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue.rb +46 -0
  145. data/lib/karafka/pro/routing/features/{direct_assignments → consumer_groups/delaying}/config.rb +6 -4
  146. data/lib/karafka/pro/routing/features/{patterns/contracts/pattern.rb → consumer_groups/delaying/contracts/topic.rb} +13 -16
  147. data/lib/karafka/pro/routing/features/consumer_groups/delaying/topic.rb +85 -0
  148. data/lib/karafka/pro/routing/features/{adaptive_iterator/config.rb → consumer_groups/delaying.rb} +8 -11
  149. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/config.rb +46 -0
  150. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/consumer_group.rb +68 -0
  151. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/topic.rb +125 -0
  152. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +97 -0
  153. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/topic.rb +97 -0
  154. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments.rb +44 -0
  155. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/config.rb +51 -0
  156. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/contracts/topic.rb +58 -0
  157. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/topic.rb +80 -0
  158. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights.rb +45 -0
  159. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/config.rb +47 -0
  160. data/lib/karafka/pro/routing/features/{multiplexing/patches/contracts/consumer_group.rb → consumer_groups/long_running_job/contracts/topic.rb} +13 -15
  161. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/topic.rb +72 -0
  162. data/lib/karafka/pro/routing/features/{long_running_job.rb → consumer_groups/long_running_job.rb} +6 -4
  163. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/config.rb +58 -0
  164. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/routing.rb +83 -0
  165. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/topic.rb +148 -0
  166. data/lib/karafka/pro/routing/features/{delaying/contracts/topic.rb → consumer_groups/multiplexing/patches/contracts/consumer_group.rb} +19 -14
  167. data/lib/karafka/pro/routing/features/{multiplexing/subscription_group.rb → consumer_groups/multiplexing/proxy.rb} +17 -23
  168. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/subscription_group.rb +68 -0
  169. data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/multiplexing}/subscription_groups_builder.rb +16 -14
  170. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing.rb +85 -0
  171. data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job/topic.rb +51 -0
  172. data/lib/karafka/pro/routing/features/{non_blocking_job.rb → consumer_groups/non_blocking_job.rb} +15 -13
  173. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/config.rb +52 -0
  174. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/contracts/topic.rb +59 -0
  175. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +93 -0
  176. data/lib/karafka/pro/routing/features/{offset_metadata.rb → consumer_groups/offset_metadata.rb} +16 -14
  177. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/builder.rb +74 -0
  178. data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/parallel_segments}/config.rb +13 -15
  179. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +110 -0
  180. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/contracts/consumer_group.rb +74 -0
  181. data/lib/karafka/pro/routing/features/{parallel_segments → consumer_groups/parallel_segments}/topic.rb +24 -22
  182. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments.rb +51 -0
  183. data/lib/karafka/pro/routing/features/{patterns → consumer_groups/patterns}/builder.rb +15 -13
  184. data/lib/karafka/pro/routing/features/{offset_metadata/contracts/topic.rb → consumer_groups/patterns/config.rb} +28 -13
  185. data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +91 -0
  186. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/consumer_group.rb +83 -0
  187. data/lib/karafka/pro/routing/features/{parallel_segments.rb → consumer_groups/patterns/contracts/pattern.rb} +24 -10
  188. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/topic.rb +58 -0
  189. data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +98 -0
  190. data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +114 -0
  191. data/lib/karafka/pro/routing/features/{recurring_tasks/contracts/topic.rb → consumer_groups/patterns/patterns.rb} +12 -13
  192. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topic.rb +78 -0
  193. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +72 -0
  194. data/lib/karafka/pro/routing/features/consumer_groups/patterns.rb +52 -0
  195. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/config.rb +56 -0
  196. data/lib/karafka/pro/routing/features/{direct_assignments/contracts/consumer_group.rb → consumer_groups/periodic_job/contracts/topic.rb} +17 -22
  197. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +122 -0
  198. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job.rb +46 -0
  199. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +150 -0
  200. data/lib/karafka/pro/routing/features/{swarm → consumer_groups/recurring_tasks}/config.rb +7 -8
  201. data/lib/karafka/pro/routing/features/{inline_insights → consumer_groups/recurring_tasks}/contracts/topic.rb +14 -13
  202. data/lib/karafka/pro/routing/features/{scheduled_messages → consumer_groups/recurring_tasks}/proxy.rb +6 -4
  203. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/topic.rb +72 -0
  204. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks.rb +44 -0
  205. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +154 -0
  206. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/config.rb +47 -0
  207. data/lib/karafka/pro/routing/features/{long_running_job → consumer_groups/scheduled_messages}/contracts/topic.rb +14 -12
  208. data/lib/karafka/pro/routing/features/{delaying/config.rb → consumer_groups/scheduled_messages/proxy.rb} +6 -4
  209. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +72 -0
  210. data/lib/karafka/pro/routing/features/{recurring_tasks/proxy.rb → consumer_groups/scheduled_messages.rb} +3 -4
  211. data/lib/karafka/pro/routing/features/{non_blocking_job/topic.rb → consumer_groups/swarm/config.rb} +9 -8
  212. data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/routing.rb +94 -0
  213. data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/topic.rb +95 -0
  214. data/lib/karafka/pro/routing/features/consumer_groups/swarm/topic.rb +105 -0
  215. data/lib/karafka/pro/routing/features/consumer_groups/swarm.rb +58 -0
  216. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/config.rb +69 -0
  217. data/lib/karafka/pro/routing/features/{parallel_segments/contracts/consumer_group.rb → consumer_groups/virtual_partitions/contracts/topic.rb} +21 -18
  218. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +101 -0
  219. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions.rb +46 -0
  220. data/lib/karafka/pro/routing/features/{scheduled_messages.rb → consumer_groups.rb} +3 -2
  221. data/lib/karafka/pro/routing/features/expiring/topic.rb +4 -4
  222. data/lib/karafka/pro/routing/features/filtering/topic.rb +3 -3
  223. data/lib/karafka/pro/routing/features/pausing/topic.rb +3 -3
  224. data/lib/karafka/pro/routing/features/throttling/topic.rb +4 -4
  225. data/lib/karafka/processing/consumer_groups/coordinator.rb +221 -0
  226. data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +69 -0
  227. data/lib/karafka/processing/consumer_groups/executor.rb +220 -0
  228. data/lib/karafka/processing/consumer_groups/executors_buffer.rb +94 -0
  229. data/lib/karafka/processing/consumer_groups/expansions_selector.rb +26 -0
  230. data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +47 -0
  231. data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +23 -0
  232. data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +132 -0
  233. data/lib/karafka/processing/consumer_groups/jobs/consume.rb +52 -0
  234. data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +34 -0
  235. data/lib/karafka/processing/consumer_groups/jobs/idle.rb +33 -0
  236. data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +34 -0
  237. data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +32 -0
  238. data/lib/karafka/processing/consumer_groups/jobs_builder.rb +36 -0
  239. data/lib/karafka/processing/consumer_groups/partitioner.rb +28 -0
  240. data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +48 -0
  241. data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +25 -0
  242. data/lib/karafka/processing/consumer_groups/strategies/base.rb +65 -0
  243. data/lib/karafka/processing/consumer_groups/strategies/default.rb +218 -0
  244. data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +157 -0
  245. data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +72 -0
  246. data/lib/karafka/processing/consumer_groups/strategies/mom.rb +33 -0
  247. data/lib/karafka/processing/consumer_groups/strategy_selector.rb +53 -0
  248. data/lib/karafka/processing/coordinator.rb +4 -211
  249. data/lib/karafka/processing/coordinators_buffer.rb +4 -59
  250. data/lib/karafka/processing/partitioner.rb +4 -18
  251. data/lib/karafka/processing/schedulers/default.rb +2 -1
  252. data/lib/karafka/processing/strategy_selector.rb +4 -42
  253. data/lib/karafka/processing/worker.rb +1 -2
  254. data/lib/karafka/routing/builder.rb +12 -12
  255. data/lib/karafka/routing/contracts/routing.rb +3 -4
  256. data/lib/karafka/routing/features/base/expander.rb +5 -5
  257. data/lib/karafka/routing/features/consumer_groups/active_job/builder.rb +35 -0
  258. data/lib/karafka/routing/features/consumer_groups/active_job/config.rb +17 -0
  259. data/lib/karafka/routing/features/consumer_groups/active_job/contracts/topic.rb +44 -0
  260. data/lib/karafka/routing/features/consumer_groups/active_job/proxy.rb +16 -0
  261. data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +50 -0
  262. data/lib/karafka/routing/features/consumer_groups/active_job.rb +15 -0
  263. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/config.rb +39 -0
  264. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/contracts/topic.rb +58 -0
  265. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/topic.rb +76 -0
  266. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue.rb +18 -0
  267. data/lib/karafka/routing/features/consumer_groups/eofed/config.rb +17 -0
  268. data/lib/karafka/routing/features/consumer_groups/eofed/contracts/topic.rb +39 -0
  269. data/lib/karafka/routing/features/consumer_groups/eofed/topic.rb +42 -0
  270. data/lib/karafka/routing/features/consumer_groups/eofed.rb +16 -0
  271. data/lib/karafka/routing/features/consumer_groups/inline_insights/config.rb +17 -0
  272. data/lib/karafka/routing/features/consumer_groups/inline_insights/contracts/topic.rb +27 -0
  273. data/lib/karafka/routing/features/consumer_groups/inline_insights/topic.rb +42 -0
  274. data/lib/karafka/routing/features/consumer_groups/inline_insights.rb +42 -0
  275. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/config.rb +17 -0
  276. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/contracts/topic.rb +27 -0
  277. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +46 -0
  278. data/lib/karafka/routing/features/consumer_groups/manual_offset_management.rb +20 -0
  279. data/lib/karafka/routing/features/consumer_groups.rb +12 -0
  280. data/lib/karafka/routing/features/declaratives/contracts/topic.rb +4 -19
  281. data/lib/karafka/routing/features/declaratives/topic.rb +30 -14
  282. data/lib/karafka/routing/features/deserializers/topic.rb +3 -3
  283. data/lib/karafka/routing/router.rb +2 -2
  284. data/lib/karafka/routing/subscription_group.rb +18 -9
  285. data/lib/karafka/routing/topic.rb +25 -11
  286. data/lib/karafka/server.rb +4 -0
  287. data/lib/karafka/setup/config.rb +64 -15
  288. data/lib/karafka/setup/config_proxy.rb +1 -2
  289. data/lib/karafka/setup/contracts/config.rb +11 -8
  290. data/lib/karafka/status.rb +1 -2
  291. data/lib/karafka/swarm/node.rb +8 -0
  292. data/lib/karafka/swarm/supervisor.rb +9 -1
  293. data/lib/karafka/templates/karafka.rb.erb +11 -5
  294. data/lib/karafka/version.rb +1 -1
  295. metadata +235 -223
  296. data/lib/karafka/connection/rebalance_manager.rb +0 -116
  297. data/lib/karafka/instrumentation/callbacks/error.rb +0 -52
  298. data/lib/karafka/instrumentation/callbacks/rebalance.rb +0 -84
  299. data/lib/karafka/instrumentation/callbacks/statistics.rb +0 -55
  300. data/lib/karafka/pro/processing/adaptive_iterator/consumer.rb +0 -79
  301. data/lib/karafka/pro/processing/adaptive_iterator/tracker.rb +0 -92
  302. data/lib/karafka/pro/processing/collapser.rb +0 -79
  303. data/lib/karafka/pro/processing/coordinator.rb +0 -197
  304. data/lib/karafka/pro/processing/coordinators/errors_tracker.rb +0 -119
  305. data/lib/karafka/pro/processing/coordinators/filters_applier.rb +0 -152
  306. data/lib/karafka/pro/processing/coordinators/virtual_offset_manager.rb +0 -207
  307. data/lib/karafka/pro/processing/expansions_selector.rb +0 -52
  308. data/lib/karafka/pro/processing/filters/delayer.rb +0 -87
  309. data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +0 -95
  310. data/lib/karafka/pro/processing/filters/throttler.rb +0 -101
  311. data/lib/karafka/pro/processing/filters/virtual_limiter.rb +0 -74
  312. data/lib/karafka/pro/processing/jobs/eofed_non_blocking.rb +0 -51
  313. data/lib/karafka/pro/processing/jobs_builder.rb +0 -90
  314. data/lib/karafka/pro/processing/offset_metadata/consumer.rb +0 -61
  315. data/lib/karafka/pro/processing/offset_metadata/fetcher.rb +0 -149
  316. data/lib/karafka/pro/processing/offset_metadata/listener.rb +0 -63
  317. data/lib/karafka/pro/processing/parallel_segments/filters/base.rb +0 -98
  318. data/lib/karafka/pro/processing/parallel_segments/filters/default.rb +0 -110
  319. data/lib/karafka/pro/processing/parallel_segments/filters/mom.rb +0 -91
  320. data/lib/karafka/pro/processing/periodic_job/consumer.rb +0 -85
  321. data/lib/karafka/pro/processing/piping/consumer.rb +0 -149
  322. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +0 -94
  323. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +0 -87
  324. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +0 -85
  325. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +0 -81
  326. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +0 -85
  327. data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +0 -79
  328. data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +0 -84
  329. data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +0 -86
  330. data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +0 -54
  331. data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +0 -101
  332. data/lib/karafka/pro/processing/strategies/base.rb +0 -43
  333. data/lib/karafka/pro/processing/strategies/default.rb +0 -416
  334. data/lib/karafka/pro/processing/strategies/dlq/default.rb +0 -280
  335. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +0 -90
  336. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +0 -92
  337. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +0 -60
  338. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +0 -58
  339. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +0 -92
  340. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +0 -58
  341. data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +0 -57
  342. data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +0 -95
  343. data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +0 -56
  344. data/lib/karafka/pro/processing/strategies/dlq/mom.rb +0 -91
  345. data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +0 -54
  346. data/lib/karafka/pro/processing/strategies/dlq/vp.rb +0 -57
  347. data/lib/karafka/pro/processing/strategies/ftr/default.rb +0 -141
  348. data/lib/karafka/pro/processing/strategies/ftr/vp.rb +0 -57
  349. data/lib/karafka/pro/processing/strategies/lrj/default.rb +0 -114
  350. data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +0 -89
  351. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +0 -87
  352. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +0 -57
  353. data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +0 -56
  354. data/lib/karafka/pro/processing/strategies/lrj/mom.rb +0 -96
  355. data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +0 -54
  356. data/lib/karafka/pro/processing/strategies/vp/default.rb +0 -192
  357. data/lib/karafka/pro/processing/strategies.rb +0 -39
  358. data/lib/karafka/pro/processing/strategy_selector.rb +0 -102
  359. data/lib/karafka/pro/processing/subscription_groups_coordinator.rb +0 -68
  360. data/lib/karafka/pro/processing/virtual_partitions/distributors/balanced.rb +0 -77
  361. data/lib/karafka/pro/routing/features/active_job.rb +0 -43
  362. data/lib/karafka/pro/routing/features/adaptive_iterator/contracts/topic.rb +0 -89
  363. data/lib/karafka/pro/routing/features/adaptive_iterator/topic.rb +0 -88
  364. data/lib/karafka/pro/routing/features/adaptive_iterator.rb +0 -48
  365. data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +0 -74
  366. data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +0 -68
  367. data/lib/karafka/pro/routing/features/dead_letter_queue.rb +0 -44
  368. data/lib/karafka/pro/routing/features/delaying/topic.rb +0 -83
  369. data/lib/karafka/pro/routing/features/delaying.rb +0 -46
  370. data/lib/karafka/pro/routing/features/direct_assignments/contracts/topic.rb +0 -123
  371. data/lib/karafka/pro/routing/features/direct_assignments/subscription_group.rb +0 -95
  372. data/lib/karafka/pro/routing/features/direct_assignments/topic.rb +0 -95
  373. data/lib/karafka/pro/routing/features/direct_assignments.rb +0 -42
  374. data/lib/karafka/pro/routing/features/inline_insights/topic.rb +0 -78
  375. data/lib/karafka/pro/routing/features/inline_insights.rb +0 -43
  376. data/lib/karafka/pro/routing/features/long_running_job/config.rb +0 -45
  377. data/lib/karafka/pro/routing/features/long_running_job/topic.rb +0 -70
  378. data/lib/karafka/pro/routing/features/multiplexing/contracts/routing.rb +0 -81
  379. data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +0 -146
  380. data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +0 -58
  381. data/lib/karafka/pro/routing/features/multiplexing.rb +0 -83
  382. data/lib/karafka/pro/routing/features/offset_metadata/config.rb +0 -50
  383. data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +0 -91
  384. data/lib/karafka/pro/routing/features/parallel_segments/builder.rb +0 -72
  385. data/lib/karafka/pro/routing/features/parallel_segments/config.rb +0 -52
  386. data/lib/karafka/pro/routing/features/parallel_segments/consumer_group.rb +0 -108
  387. data/lib/karafka/pro/routing/features/patterns/config.rb +0 -71
  388. data/lib/karafka/pro/routing/features/patterns/consumer_group.rb +0 -89
  389. data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +0 -56
  390. data/lib/karafka/pro/routing/features/patterns/detector.rb +0 -96
  391. data/lib/karafka/pro/routing/features/patterns/pattern.rb +0 -112
  392. data/lib/karafka/pro/routing/features/patterns/topic.rb +0 -76
  393. data/lib/karafka/pro/routing/features/patterns/topics.rb +0 -70
  394. data/lib/karafka/pro/routing/features/patterns.rb +0 -50
  395. data/lib/karafka/pro/routing/features/periodic_job/config.rb +0 -54
  396. data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +0 -59
  397. data/lib/karafka/pro/routing/features/periodic_job/topic.rb +0 -120
  398. data/lib/karafka/pro/routing/features/periodic_job.rb +0 -44
  399. data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +0 -148
  400. data/lib/karafka/pro/routing/features/recurring_tasks/config.rb +0 -45
  401. data/lib/karafka/pro/routing/features/recurring_tasks/topic.rb +0 -70
  402. data/lib/karafka/pro/routing/features/recurring_tasks.rb +0 -42
  403. data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +0 -152
  404. data/lib/karafka/pro/routing/features/scheduled_messages/config.rb +0 -45
  405. data/lib/karafka/pro/routing/features/scheduled_messages/contracts/topic.rb +0 -55
  406. data/lib/karafka/pro/routing/features/scheduled_messages/topic.rb +0 -70
  407. data/lib/karafka/pro/routing/features/swarm/contracts/routing.rb +0 -92
  408. data/lib/karafka/pro/routing/features/swarm/contracts/topic.rb +0 -93
  409. data/lib/karafka/pro/routing/features/swarm/topic.rb +0 -103
  410. data/lib/karafka/pro/routing/features/swarm.rb +0 -56
  411. data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +0 -67
  412. data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +0 -73
  413. data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +0 -99
  414. data/lib/karafka/pro/routing/features/virtual_partitions.rb +0 -44
  415. data/lib/karafka/processing/executor.rb +0 -216
  416. data/lib/karafka/processing/executors_buffer.rb +0 -90
  417. data/lib/karafka/processing/expansions_selector.rb +0 -22
  418. data/lib/karafka/processing/inline_insights/consumer.rb +0 -43
  419. data/lib/karafka/processing/inline_insights/listener.rb +0 -19
  420. data/lib/karafka/processing/inline_insights/tracker.rb +0 -129
  421. data/lib/karafka/processing/jobs/consume.rb +0 -47
  422. data/lib/karafka/processing/jobs/eofed.rb +0 -29
  423. data/lib/karafka/processing/jobs/idle.rb +0 -31
  424. data/lib/karafka/processing/jobs/revoked.rb +0 -29
  425. data/lib/karafka/processing/jobs/shutdown.rb +0 -30
  426. data/lib/karafka/processing/jobs_builder.rb +0 -34
  427. data/lib/karafka/processing/strategies/aj_dlq_mom.rb +0 -44
  428. data/lib/karafka/processing/strategies/aj_mom.rb +0 -21
  429. data/lib/karafka/processing/strategies/base.rb +0 -61
  430. data/lib/karafka/processing/strategies/default.rb +0 -214
  431. data/lib/karafka/processing/strategies/dlq.rb +0 -153
  432. data/lib/karafka/processing/strategies/dlq_mom.rb +0 -68
  433. data/lib/karafka/processing/strategies/mom.rb +0 -29
  434. data/lib/karafka/routing/features/active_job/builder.rb +0 -33
  435. data/lib/karafka/routing/features/active_job/config.rb +0 -15
  436. data/lib/karafka/routing/features/active_job/contracts/topic.rb +0 -42
  437. data/lib/karafka/routing/features/active_job/proxy.rb +0 -14
  438. data/lib/karafka/routing/features/active_job/topic.rb +0 -48
  439. data/lib/karafka/routing/features/active_job.rb +0 -13
  440. data/lib/karafka/routing/features/dead_letter_queue/config.rb +0 -37
  441. data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +0 -56
  442. data/lib/karafka/routing/features/dead_letter_queue/topic.rb +0 -74
  443. data/lib/karafka/routing/features/dead_letter_queue.rb +0 -16
  444. data/lib/karafka/routing/features/declaratives/config.rb +0 -18
  445. data/lib/karafka/routing/features/eofed/config.rb +0 -15
  446. data/lib/karafka/routing/features/eofed/contracts/topic.rb +0 -37
  447. data/lib/karafka/routing/features/eofed/topic.rb +0 -40
  448. data/lib/karafka/routing/features/eofed.rb +0 -14
  449. data/lib/karafka/routing/features/inline_insights/config.rb +0 -15
  450. data/lib/karafka/routing/features/inline_insights/contracts/topic.rb +0 -25
  451. data/lib/karafka/routing/features/inline_insights/topic.rb +0 -40
  452. data/lib/karafka/routing/features/inline_insights.rb +0 -40
  453. data/lib/karafka/routing/features/manual_offset_management/config.rb +0 -15
  454. data/lib/karafka/routing/features/manual_offset_management/contracts/topic.rb +0 -25
  455. data/lib/karafka/routing/features/manual_offset_management/topic.rb +0 -44
  456. data/lib/karafka/routing/features/manual_offset_management.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 953c11ca73eda62bac76aaca94946b50b880a54e50756b0665da68155c9ad68d
4
- data.tar.gz: a5d200ac66bc102d6dac680aaa03df1cc897113dc2af52f4684f3f7128608340
3
+ metadata.gz: 04dfc2086393c6d3d1b8c78eca503c425842453163b014dcba68a5c4231fe090
4
+ data.tar.gz: 5f62160e469b6eb2383234f630654b46fe704e9dedd896e863771c945ab8e30e
5
5
  SHA512:
6
- metadata.gz: 96d8087bda95065a1b56f5a525b9dd53c9ec71d01d9dd51f56403f7a14fd5ee406f2c40a366e1bb607495ebea8ce76ddd379df08e8e76594cdfae5905ff9c3d0
7
- data.tar.gz: 393f0264db679e7b71eeb2fe6c419090d6ff46a43354789fcef2e1e7e6baec3c839583982129669d02a6eae1d245396f48c0dcfebe475946ca2aa97dadce90ed
6
+ metadata.gz: 3f1bb0b95294bb925b71ff4cd91d0603b538b4f7f9a222a4789aa9aeef89f7f80b8b26ebf2623f1c44585e1de1d87d4be6dbb55748f61de9b1dd90cab68059d7
7
+ data.tar.gz: 1c79e3b072d6b53c0062f0ade986f357f677cae6d476297389732c3c130fd89e84687526729ba2590763d15d5f0279e08e3ca9fceec386401b2d9d5ec3ef2096
data/CHANGELOG.md CHANGED
@@ -1,6 +1,24 @@
1
1
  # Karafka Framework Changelog
2
2
 
3
- ## 2.5.10 (Unreleased)
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
22
  - **[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.
5
23
  - [Enhancement] Add per-partition generation tracking to `AssignmentsTracker` to distinguish first-time assignments from reassignments.
6
24
  - [Enhancement] Make liveness listeners fiber-safe.
@@ -9,8 +27,12 @@
9
27
  - [Fix] Fire liveness events during `wait_pinging` so nodes continue reporting health status during shutdown with active LRJ jobs.
10
28
  - [Maintenance] Use namespaced topic naming format in all integration specs for consistent traceability.
11
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`.
12
31
  - [Maintenance] Add `bin/tests_topics_hashes` script for looking up spec files by their topic name hash prefix.
13
- - [Change] Require `karafka-rdkafka` `>=` `0.26.1` to support upcoming features relying on low-level Rdkafka APIs.
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`.
14
36
 
15
37
  ## 2.5.9 (2026-03-30)
16
38
  - [Enhancement] Validate that `statistics.interval.ms` is not zero when dynamic multiplexing is enabled (Pro).
@@ -34,16 +34,16 @@ en:
34
34
 
35
35
  oauth.token_provider_listener_format: 'must be false or respond to #on_oauthbearer_token_refresh'
36
36
 
37
- internal.processing.jobs_builder_format: cannot be nil
38
37
  internal.processing.jobs_queue_class_format: cannot be nil
39
38
  internal.processing.scheduler_class_format: cannot be nil
40
- internal.processing.coordinator_class_format: cannot be nil
41
- internal.processing.partitioner_class_format: cannot be nil
42
- internal.processing.strategy_selector_format: cannot be nil
43
- internal.processing.expansions_selector_format: cannot be nil
44
- internal.processing.executor_class_format: cannot be nil
45
39
  internal.processing.worker_job_call_wrapper_format: 'needs to be false or respond to #wrap'
46
- internal.processing.errors_tracker_class_format: 'needs to be nil or a class'
40
+ internal.processing.consumer_groups.jobs_builder_format: cannot be nil
41
+ internal.processing.consumer_groups.coordinator_class_format: cannot be nil
42
+ internal.processing.consumer_groups.errors_tracker_class_format: 'needs to be nil or a class'
43
+ internal.processing.consumer_groups.partitioner_class_format: cannot be nil
44
+ internal.processing.consumer_groups.strategy_selector_format: cannot be nil
45
+ internal.processing.consumer_groups.expansions_selector_format: cannot be nil
46
+ internal.processing.consumer_groups.executor_class_format: cannot be nil
47
47
 
48
48
  internal.active_job.dispatcher_format: cannot be nil
49
49
  internal.active_job.job_options_contract_format: cannot be nil
@@ -176,6 +176,13 @@ en:
176
176
  all topic names within a single consumer group must be unique considering namespacing styles
177
177
  disable this validation by setting config.strict_topics_namespacing to false
178
178
 
179
+ declaratives:
180
+ topic:
181
+ declaratives.partitions_format: needs to be more or equal to 1
182
+ declaratives.active_format: needs to be either true or false
183
+ declaratives.replication_factor_format: needs to be more or equal to 1
184
+ declaratives.details_format: needs to be a hash with only symbol keys
185
+
179
186
  job_options:
180
187
  missing: needs to be present
181
188
  dispatch_method_format: needs to be either :produce_async or :produce_sync
data/karafka.gemspec CHANGED
@@ -21,9 +21,9 @@ 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 "karafka-core", ">= 2.5.13", "< 2.6.0"
25
- spec.add_dependency "karafka-rdkafka", ">= 0.26.1"
26
- spec.add_dependency "waterdrop", ">= 2.8.14", "< 3.0.0"
24
+ spec.add_dependency "karafka-core", ">= 2.6.0", "< 2.7.0"
25
+ spec.add_dependency "karafka-rdkafka", ">= 0.27.2"
26
+ spec.add_dependency "waterdrop", ">= 2.10.1", "< 3.0.0"
27
27
  spec.add_dependency "zeitwerk", "~> 2.3"
28
28
 
29
29
  spec.required_ruby_version = ">= 3.2.0"
@@ -28,8 +28,7 @@ module ActiveJob
28
28
  Object
29
29
  end
30
30
 
31
- # Karafka adapter for enqueuing jobs
32
- # This is here for ease of integration with ActiveJob.
31
+ # Karafka adapter for enqueuing jobs This is here for ease of integration with ActiveJob.
33
32
  class KarafkaAdapter < base
34
33
  include ::Karafka::Helpers::ConfigImporter.new(
35
34
  dispatcher: %i[internal active_job dispatcher]
@@ -19,8 +19,7 @@ module Karafka
19
19
  def karafka_options(new_options = {})
20
20
  return _karafka_options if new_options.empty?
21
21
 
22
- # Make sure, that karafka options that someone wants to use are valid before assigning
23
- # them
22
+ # Make sure, that karafka options that someone wants to use are valid before assigning them
24
23
  App.config.internal.active_job.job_options_contract.validate!(
25
24
  new_options,
26
25
  scope: %w[active_job]
@@ -76,8 +76,7 @@ module Karafka
76
76
 
77
77
  private
78
78
 
79
- # Recognizes whether the type is provided and remaps it to a symbol representation if
80
- # needed
79
+ # Recognizes whether the type is provided and remaps it to a symbol representation if needed
81
80
  #
82
81
  # @param type [Symbol, Integer]
83
82
  # @return [Symbol]
@@ -18,65 +18,64 @@ module Karafka
18
18
  private_constant :LONG_TIME_AGO, :DAY_IN_SECONDS
19
19
 
20
20
  class << self
21
- # @param consumer_group_id [String] consumer group for which we want to move offsets
21
+ # @param group_id [String] group for which we want to move offsets
22
22
  # @param topics_with_partitions_and_offsets [Hash] hash with topics and settings
23
23
  # @see #seek
24
- def seek(consumer_group_id, topics_with_partitions_and_offsets)
25
- new.seek(consumer_group_id, topics_with_partitions_and_offsets)
24
+ def seek(group_id, topics_with_partitions_and_offsets)
25
+ new.seek(group_id, topics_with_partitions_and_offsets)
26
26
  end
27
27
 
28
- # @param previous_name [String] old consumer group name
29
- # @param new_name [String] new consumer group name
28
+ # @param previous_name [String] old group name
29
+ # @param new_name [String] new group name
30
30
  # @param topics [Array<String>] topics for which we want to copy offsets
31
31
  # @see #copy
32
32
  def copy(previous_name, new_name, topics)
33
33
  new.copy(previous_name, new_name, topics)
34
34
  end
35
35
 
36
- # @param previous_name [String] old consumer group name
37
- # @param new_name [String] new consumer group name
36
+ # @param previous_name [String] old group name
37
+ # @param new_name [String] new group name
38
38
  # @param topics [Array<String>] topics for which we want to migrate offsets
39
- # @param delete_previous [Boolean] should we delete previous consumer group after rename
39
+ # @param delete_previous [Boolean] should we delete previous group after rename
40
40
  # @see #rename
41
41
  def rename(previous_name, new_name, topics, delete_previous: true)
42
42
  new.rename(previous_name, new_name, topics, delete_previous: delete_previous)
43
43
  end
44
44
 
45
- # @param consumer_group_id [String] consumer group name
45
+ # @param group_id [String] group name
46
46
  # @see #delete
47
- def delete(consumer_group_id)
48
- new.delete(consumer_group_id)
47
+ def delete(group_id)
48
+ new.delete(group_id)
49
49
  end
50
50
 
51
- # @param consumer_group_id [String] consumer group id to trigger rebalance for
51
+ # @param group_id [String] group id to trigger rebalance for
52
52
  # @see #trigger_rebalance
53
- def trigger_rebalance(consumer_group_id)
54
- new.trigger_rebalance(consumer_group_id)
53
+ def trigger_rebalance(group_id)
54
+ new.trigger_rebalance(group_id)
55
55
  end
56
56
 
57
- # @param consumer_groups_with_topics [Hash{String => Array<String>}] hash with consumer
58
- # groups names with array of topics
57
+ # @param groups_with_topics [Hash{String => Array<String>}] hash with group names with
58
+ # array of topics
59
59
  # @param active_topics_only [Boolean] if set to false, will select also inactive topics
60
60
  # @see #read_lags_with_offsets
61
- def read_lags_with_offsets(consumer_groups_with_topics = {}, active_topics_only: true)
61
+ def read_lags_with_offsets(groups_with_topics = {}, active_topics_only: true)
62
62
  new.read_lags_with_offsets(
63
- consumer_groups_with_topics,
63
+ groups_with_topics,
64
64
  active_topics_only: active_topics_only
65
65
  )
66
66
  end
67
67
  end
68
68
 
69
- # Moves the offset on a given consumer group and provided topic to the requested location
69
+ # Moves the offset on a given group and provided topic to the requested location
70
70
  #
71
- # @param consumer_group_id [String] id of the consumer group for which we want to move the
72
- # existing offset
71
+ # @param group_id [String] id of the group for which we want to move the existing offset
73
72
  # @param topics_with_partitions_and_offsets [Hash] Hash with list of topics and settings to
74
73
  # where to move given consumer. It allows us to move particular partitions or whole
75
74
  # topics if we want to reset all partitions to for example a point in time.
76
75
  #
77
76
  # @return [void]
78
77
  #
79
- # @note This method should **not** be executed on a running consumer group as it creates a
78
+ # @note This method should **not** be executed on a running group as it creates a
80
79
  # "fake" consumer and uses it to move offsets.
81
80
  #
82
81
  # @example Move a single topic partition nr 1 offset to 100
@@ -99,7 +98,7 @@ module Karafka
99
98
  #
100
99
  # @example Move offset of a single partition to latest
101
100
  # Karafka::Admin::ConsumerGroups.seek('group-id', { 'topic' => { 1 => 'latest' } })
102
- def seek(consumer_group_id, topics_with_partitions_and_offsets)
101
+ def seek(group_id, topics_with_partitions_and_offsets)
103
102
  tpl_base = {}
104
103
 
105
104
  # Normalize the data so we always have all partitions and topics in the same format
@@ -161,28 +160,41 @@ module Karafka
161
160
  end
162
161
  end
163
162
 
164
- settings = { "group.id": consumer_group_id }
163
+ settings = { "group.id": group_id }
165
164
 
166
165
  with_consumer(settings) do |consumer|
167
166
  # If we have any time based stuff to resolve, we need to do it prior to commits
168
167
  unless time_tpl.empty?
169
168
  real_offsets = consumer.offsets_for_times(time_tpl)
170
169
 
171
- real_offsets.to_h.each do |name, results|
170
+ # Collect all partitions where the timestamp is beyond the last message
171
+ # (negative offset returned) so we can fetch their HWMs in a single batch
172
+ # admin call instead of one per-partition consumer call
173
+ real_offsets_by_topic = real_offsets.to_h
174
+ hwm_specs = {}
175
+ real_offsets_by_topic.each do |name, results|
172
176
  results.each do |result|
173
177
  raise(Errors::InvalidTimeBasedOffsetError) unless result
178
+ next unless result.offset.negative?
174
179
 
175
- partition = result.partition
180
+ (hwm_specs[name] ||= []) << { partition: result.partition, offset: :latest }
181
+ end
182
+ end
176
183
 
177
- # Negative offset means we're beyond last message and we need to query for the
178
- # high watermark offset to get the most recent offset and move there
179
- if result.offset.negative?
180
- _, offset = consumer.query_watermark_offsets(name, result.partition)
181
- else
182
- # If we get an offset, it means there existed a message close to this time
183
- # location
184
- offset = result.offset
184
+ hwms = {}
185
+ unless hwm_specs.empty?
186
+ with_admin do |admin|
187
+ admin.list_offsets(hwm_specs).wait(max_wait_timeout_ms: max_wait_time_ms).offsets.each do |r|
188
+ (hwms[r[:topic]] ||= {})[r[:partition]] = r[:offset]
185
189
  end
190
+ end
191
+ end
192
+
193
+ real_offsets_by_topic.each do |name, results|
194
+ results.each do |result|
195
+ partition = result.partition
196
+ # If offset is negative the timestamp was beyond the last message; use HWM
197
+ offset = result.offset.negative? ? hwms.dig(name, partition) : result.offset
186
198
 
187
199
  # Since now we have proper offsets, we can add this to the final tpl for commit
188
200
  tpl.to_h[name] ||= []
@@ -198,18 +210,18 @@ module Karafka
198
210
  end
199
211
  end
200
212
 
201
- # Takes consumer group and its topics and copies all the offsets to a new named group
213
+ # Takes group and its topics and copies all the offsets to a new named group
202
214
  #
203
- # @param previous_name [String] old consumer group name
204
- # @param new_name [String] new consumer group name
215
+ # @param previous_name [String] old group name
216
+ # @param new_name [String] new group name
205
217
  # @param topics [Array<String>] topics for which we want to migrate offsets during rename
206
218
  #
207
219
  # @return [Boolean] true if anything was migrated, otherwise false
208
220
  #
209
- # @note This method should **not** be executed on a running consumer group as it creates a
221
+ # @note This method should **not** be executed on a running group as it creates a
210
222
  # "fake" consumer and uses it to move offsets.
211
223
  #
212
- # @note If new consumer group exists, old offsets will be added to it.
224
+ # @note If new group exists, old offsets will be added to it.
213
225
  def copy(previous_name, new_name, topics)
214
226
  remap = Hash.new { |h, k| h[k] = {} }
215
227
 
@@ -236,24 +248,24 @@ module Karafka
236
248
  true
237
249
  end
238
250
 
239
- # Takes consumer group and its topics and migrates all the offsets to a new named group
251
+ # Takes group and its topics and migrates all the offsets to a new named group
240
252
  #
241
- # @param previous_name [String] old consumer group name
242
- # @param new_name [String] new consumer group name
253
+ # @param previous_name [String] old group name
254
+ # @param new_name [String] new group name
243
255
  # @param topics [Array<String>] topics for which we want to migrate offsets during rename
244
- # @param delete_previous [Boolean] should we delete previous consumer group after rename.
256
+ # @param delete_previous [Boolean] should we delete previous group after rename.
245
257
  # Defaults to true.
246
258
  #
247
259
  # @return [Boolean] true if rename (and optionally removal) was ok or false if there was
248
260
  # nothing really to rename
249
261
  #
250
- # @note This method should **not** be executed on a running consumer group as it creates a
262
+ # @note This method should **not** be executed on a running group as it creates a
251
263
  # "fake" consumer and uses it to move offsets.
252
264
  #
253
265
  # @note After migration unless `delete_previous` is set to `false`, old group will be
254
266
  # removed.
255
267
  #
256
- # @note If new consumer group exists, old offsets will be added to it.
268
+ # @note If new group exists, old offsets will be added to it.
257
269
  def rename(previous_name, new_name, topics, delete_previous: true)
258
270
  copy_result = copy(previous_name, new_name, topics)
259
271
 
@@ -265,35 +277,35 @@ module Karafka
265
277
  true
266
278
  end
267
279
 
268
- # Removes given consumer group (if exists)
280
+ # Removes given group (if exists)
269
281
  #
270
- # @param consumer_group_id [String] consumer group name
282
+ # @param group_id [String] group name
271
283
  #
272
284
  # @return [void]
273
285
  #
274
- # @note This method should not be used on a running consumer group as it will not yield any
286
+ # @note This method should not be used on a running group as it will not yield any
275
287
  # results.
276
- def delete(consumer_group_id)
288
+ def delete(group_id)
277
289
  with_admin do |admin|
278
- handler = admin.delete_group(consumer_group_id)
290
+ handler = admin.delete_group(group_id)
279
291
  handler.wait(max_wait_timeout_ms: max_wait_time_ms)
280
292
  end
281
293
  end
282
294
 
283
- # Triggers a rebalance for the specified consumer group by briefly joining and leaving
295
+ # Triggers a rebalance for the specified group by briefly joining and leaving
284
296
  #
285
- # @param consumer_group_id [String] consumer group id to trigger rebalance for
297
+ # @param group_id [String] group id to trigger rebalance for
286
298
  #
287
299
  # @return [void]
288
300
  #
289
- # @raise [Karafka::Errors::InvalidConfigurationError] when consumer group is not found in
301
+ # @raise [Karafka::Errors::InvalidConfigurationError] when group is not found in
290
302
  # routing or has no topics
291
303
  #
292
- # @note This method creates a temporary "fake" consumer that joins the consumer group,
304
+ # @note This method creates a temporary "fake" consumer that joins the group,
293
305
  # triggering a rebalance when it joins and another when it leaves. This should only be
294
306
  # used for operational/testing purposes as it causes two rebalances.
295
307
  #
296
- # @note The consumer group does not need to be running for this to work, but if it is,
308
+ # @note The group does not need to be running for this to work, but if it is,
297
309
  # it will experience rebalances.
298
310
  #
299
311
  # @note The behavior follows the configured rebalance protocol. For cooperative sticky
@@ -302,38 +314,38 @@ module Karafka
302
314
  # stopping all consumers.
303
315
  #
304
316
  # @note Topics are always detected from the routing configuration. The consumer settings
305
- # (kafka config) are taken from the first topic in the consumer group to ensure
317
+ # (kafka config) are taken from the first topic in the group to ensure
306
318
  # consistency with the actual consumer configuration.
307
319
  #
308
- # @example Trigger rebalance for a consumer group
320
+ # @example Trigger rebalance for a group
309
321
  # Karafka::Admin::ConsumerGroups.trigger_rebalance('my-group')
310
- def trigger_rebalance(consumer_group_id)
311
- consumer_group = Karafka::App.routes.find { |cg| cg.id == consumer_group_id }
322
+ def trigger_rebalance(group_id)
323
+ group = Karafka::App.routes.find { |g| g.id == group_id }
312
324
 
313
- unless consumer_group
325
+ unless group
314
326
  raise(
315
327
  Errors::InvalidConfigurationError,
316
- "Consumer group '#{consumer_group_id}' not found in routing"
328
+ "Group '#{group_id}' not found in routing"
317
329
  )
318
330
  end
319
331
 
320
- topics = consumer_group.topics.map(&:name)
332
+ topics = group.topics.map(&:name)
321
333
 
322
334
  if topics.empty?
323
335
  raise(
324
336
  Errors::InvalidConfigurationError,
325
- "Consumer group '#{consumer_group_id}' has no topics"
337
+ "Group '#{group_id}' has no topics"
326
338
  )
327
339
  end
328
340
 
329
341
  # Get the first topic to extract kafka settings
330
- first_topic = consumer_group.topics.first
342
+ first_topic = group.topics.first
331
343
 
332
- # Build consumer settings using the consumer group's kafka config from first topic
344
+ # Build consumer settings using the group's kafka config from first topic
333
345
  # This ensures we use the same settings as the actual consumers
334
346
  # Following the same pattern as in Karafka::Connection::Client#build_kafka
335
347
  consumer_settings = Setup::AttributesMap.consumer(first_topic.kafka.dup)
336
- consumer_settings[:"group.id"] = consumer_group.id
348
+ consumer_settings[:"group.id"] = group.id
337
349
  consumer_settings[:"enable.auto.offset.store"] = false
338
350
  consumer_settings[:"auto.offset.reset"] ||= first_topic.initial_offset
339
351
 
@@ -350,26 +362,25 @@ module Karafka
350
362
  end
351
363
  end
352
364
 
353
- # Reads lags and offsets for given topics in the context of consumer groups defined in the
354
- # routing
365
+ # Reads lags and offsets for given topics in the context of groups defined in the routing
355
366
  #
356
- # @param consumer_groups_with_topics [Hash{String => Array<String>}] hash with consumer
357
- # groups names with array of topics to query per consumer group inside
367
+ # @param groups_with_topics [Hash{String => Array<String>}] hash with group names with
368
+ # array of topics to query per group inside
358
369
  # @param active_topics_only [Boolean] if set to false, when we use routing topics, will
359
370
  # select also topics that are marked as inactive in routing
360
371
  #
361
372
  # @return [Hash{String => Hash{Integer => Hash{Integer => Object}}}] hash where the top
362
- # level keys are the consumer groups and values are hashes with topics and inside
373
+ # level keys are the groups and values are hashes with topics and inside
363
374
  # partitions with lags and offsets
364
375
  #
365
376
  # @note For topics that do not exist, topic details will be set to an empty hash
366
377
  #
367
- # @note For topics that exist but were never consumed by a given CG we set `-1` as lag and
368
- # the offset on each of the partitions that were not consumed.
378
+ # @note For topics that exist but were never consumed by a given group we set `-1` as lag
379
+ # and the offset on each of the partitions that were not consumed.
369
380
  #
370
381
  # @note This lag reporting is for committed lags and is "Kafka-centric", meaning that this
371
382
  # represents lags from Kafka perspective and not the consumer. They may differ.
372
- def read_lags_with_offsets(consumer_groups_with_topics = {}, active_topics_only: true)
383
+ def read_lags_with_offsets(groups_with_topics = {}, active_topics_only: true)
373
384
  # We first fetch all the topics with partitions count that exist in the cluster so we
374
385
  # do not query for topics that do not exist and so we can get partitions count for all
375
386
  # the topics we may need. The non-existent and not consumed will be filled at the end
@@ -377,82 +388,82 @@ module Karafka
377
388
  [topic[:topic_name], topic[:partition_count]]
378
389
  end.freeze
379
390
 
380
- # If no expected CGs, we use all from routing that have active topics
381
- if consumer_groups_with_topics.empty?
382
- consumer_groups_with_topics = Karafka::App.routes.to_h do |cg|
383
- cg_topics = cg.topics.select do |cg_topic|
384
- active_topics_only ? cg_topic.active? : true
391
+ # If no expected groups, we use all from routing that have active topics
392
+ if groups_with_topics.empty?
393
+ groups_with_topics = Karafka::App.routes.to_h do |group|
394
+ group_topics = group.topics.select do |group_topic|
395
+ active_topics_only ? group_topic.active? : true
385
396
  end
386
397
 
387
- [cg.id, cg_topics.map(&:name)]
398
+ [group.id, group_topics.map(&:name)]
388
399
  end
389
400
  end
390
401
 
391
402
  # We make a copy because we will remove once with non-existing topics
392
- # We keep original requested consumer groups with topics for later backfilling
393
- cgs_with_topics = consumer_groups_with_topics.dup
394
- cgs_with_topics.transform_values!(&:dup)
403
+ # We keep original requested groups with topics for later backfilling
404
+ queryable_groups = groups_with_topics.dup
405
+ queryable_groups.transform_values!(&:dup)
395
406
 
396
407
  # We can query only topics that do exist, this is why we are cleaning those that do not
397
408
  # exist
398
- cgs_with_topics.each_value do |requested_topics|
409
+ queryable_groups.each_value do |requested_topics|
399
410
  requested_topics.delete_if { |topic| !existing_topics.include?(topic) }
400
411
  end
401
412
 
402
413
  groups_lags = Hash.new { |h, k| h[k] = {} }
403
414
  groups_offs = Hash.new { |h, k| h[k] = {} }
404
415
 
405
- cgs_with_topics.each do |cg, topics|
416
+ queryable_groups.each do |group, topics|
406
417
  # Do not add to tpl topics that do not exist
407
418
  next if topics.empty?
408
419
 
409
420
  tpl = Rdkafka::Consumer::TopicPartitionList.new
410
421
 
411
- with_consumer("group.id": cg) do |consumer|
422
+ with_consumer("group.id": group) do |consumer|
412
423
  topics.each { |topic| tpl.add_topic(topic, existing_topics[topic]) }
413
424
 
414
425
  commit_offsets = consumer.committed(tpl)
415
426
 
416
427
  commit_offsets.to_h.each do |topic, partitions|
417
- groups_offs[cg][topic] = {}
428
+ groups_offs[group][topic] = {}
418
429
 
419
430
  partitions.each do |partition|
420
431
  # -1 when no offset is stored
421
- groups_offs[cg][topic][partition.partition] = partition.offset || -1
432
+ groups_offs[group][topic][partition.partition] = partition.offset || -1
422
433
  end
423
434
  end
424
435
 
425
436
  consumer.lag(commit_offsets).each do |topic, partitions_lags|
426
- groups_lags[cg][topic] = partitions_lags
437
+ groups_lags[group][topic] = partitions_lags
427
438
  end
428
439
  end
429
440
  end
430
441
 
431
- consumer_groups_with_topics.each do |cg, topics|
432
- groups_lags[cg]
442
+ groups_with_topics.each do |group, topics|
443
+ groups_lags[group]
433
444
 
434
445
  topics.each do |topic|
435
- groups_lags[cg][topic] ||= {}
446
+ groups_lags[group][topic] ||= {}
436
447
 
437
448
  next unless existing_topics.key?(topic)
438
449
 
439
- # We backfill because there is a case where our consumer group would consume for
450
+ # We backfill because there is a case where our group would consume for
440
451
  # example only one partition out of 20, rest needs to get -1
441
452
  existing_topics[topic].times do |partition_id|
442
- groups_lags[cg][topic][partition_id] ||= -1
453
+ groups_lags[group][topic][partition_id] ||= -1
443
454
  end
444
455
  end
445
456
  end
446
457
 
447
458
  merged = Hash.new { |h, k| h[k] = {} }
448
459
 
449
- groups_lags.each do |cg, topics|
460
+ groups_lags.each do |group, topics|
450
461
  topics.each do |topic, partitions|
451
- merged[cg][topic] = {}
462
+ merged[group][topic] = {}
452
463
 
453
464
  partitions.each do |partition, lag|
454
- merged[cg][topic][partition] = {
455
- offset: groups_offs.fetch(cg).fetch(topic).fetch(partition),
465
+ merged[group][topic][partition] = {
466
+ offset: groups_offs.fetch(group).fetch(topic).fetch(partition),
456
467
  lag: lag
457
468
  }
458
469
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ class Admin
5
+ # Isolation level constants for Kafka operations.
6
+ #
7
+ # Controls whether a query returns the high-watermark (includes messages from uncommitted
8
+ # or in-flight transactions) or the Last Stable Offset (excludes them).
9
+ #
10
+ # For non-transactional topics both values give the same result.
11
+ module IsolationLevels
12
+ # Default. Returns the high-watermark offset, which includes messages written by
13
+ # producers that have not yet committed (or aborted) their transaction.
14
+ READ_UNCOMMITTED = Rdkafka::Bindings::RD_KAFKA_ISOLATION_LEVEL_READ_UNCOMMITTED
15
+
16
+ # Returns the Last Stable Offset (LSO): the highest offset that a READ_COMMITTED
17
+ # consumer would actually see. Use this when computing lag on topics produced with
18
+ # transactional producers, otherwise the high-watermark overstates lag.
19
+ READ_COMMITTED = Rdkafka::Bindings::RD_KAFKA_ISOLATION_LEVEL_READ_COMMITTED
20
+ end
21
+ end
22
+ end