karafka 2.5.9 → 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 (471) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/certs/expired.txt +83 -0
  4. data/config/locales/errors.yml +17 -7
  5. data/karafka.gemspec +3 -3
  6. data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -2
  7. data/lib/karafka/active_job/job_extensions.rb +1 -2
  8. data/lib/karafka/admin/configs/resource.rb +1 -2
  9. data/lib/karafka/admin/consumer_groups.rb +109 -98
  10. data/lib/karafka/admin/isolation_levels.rb +22 -0
  11. data/lib/karafka/admin/topics.rb +103 -8
  12. data/lib/karafka/admin.rb +59 -31
  13. data/lib/karafka/app.rb +16 -5
  14. data/lib/karafka/base_consumer.rb +2 -2
  15. data/lib/karafka/cli/contracts/server.rb +4 -4
  16. data/lib/karafka/cli/info.rb +1 -1
  17. data/lib/karafka/cli/topics/base.rb +10 -18
  18. data/lib/karafka/cli/topics/repartition.rb +1 -1
  19. data/lib/karafka/connection/client.rb +40 -9
  20. data/lib/karafka/connection/consumer_groups/rebalance_manager.rb +120 -0
  21. data/lib/karafka/connection/listener.rb +8 -7
  22. data/lib/karafka/connection/listeners_batch.rb +1 -1
  23. data/lib/karafka/connection/mode.rb +1 -2
  24. data/lib/karafka/connection/raw_messages_buffer.rb +0 -5
  25. data/lib/karafka/declaratives/builder.rb +65 -0
  26. data/lib/karafka/declaratives/contracts/topic.rb +28 -0
  27. data/lib/karafka/declaratives/repository.rb +52 -0
  28. data/lib/karafka/declaratives/topic.rb +100 -0
  29. data/lib/karafka/declaratives.rb +9 -0
  30. data/lib/karafka/helpers/interval_runner.rb +2 -2
  31. data/lib/karafka/instrumentation/assignments_tracker.rb +65 -2
  32. data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +56 -0
  33. data/lib/karafka/instrumentation/callbacks/consumer_groups/rebalance.rb +93 -0
  34. data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +59 -0
  35. data/lib/karafka/instrumentation/logger_listener.rb +27 -9
  36. data/lib/karafka/instrumentation/notifications.rb +2 -0
  37. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +14 -17
  38. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +8 -9
  39. data/lib/karafka/instrumentation/vendors/kubernetes/base_listener.rb +7 -3
  40. data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +13 -10
  41. data/lib/karafka/licenser.rb +16 -3
  42. data/lib/karafka/pro/active_job/consumer.rb +1 -2
  43. data/lib/karafka/pro/active_job/dispatcher.rb +1 -2
  44. data/lib/karafka/pro/admin/recovery.rb +19 -19
  45. data/lib/karafka/pro/base_consumer.rb +3 -3
  46. data/lib/karafka/pro/cli/contracts/server.rb +5 -5
  47. data/lib/karafka/pro/cli/parallel_segments/base.rb +7 -7
  48. data/lib/karafka/pro/cli/parallel_segments/collapse.rb +4 -4
  49. data/lib/karafka/pro/cli/parallel_segments/distribute.rb +6 -6
  50. data/lib/karafka/pro/iterator/tpl_builder.rb +38 -18
  51. data/lib/karafka/pro/loader.rb +15 -12
  52. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +84 -0
  53. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +97 -0
  54. data/lib/karafka/pro/processing/consumer_groups/collapser.rb +84 -0
  55. data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +202 -0
  56. data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +124 -0
  57. data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +157 -0
  58. data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +212 -0
  59. data/lib/karafka/pro/processing/{filters/expirer.rb → consumer_groups/executor.rb} +17 -31
  60. data/lib/karafka/pro/processing/{jobs/periodic.rb → consumer_groups/expansions_selector.rb} +18 -21
  61. data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +103 -0
  62. data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +92 -0
  63. data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +78 -0
  64. data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +99 -0
  65. data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +106 -0
  66. data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +79 -0
  67. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/consume_non_blocking.rb +21 -17
  68. data/lib/karafka/pro/processing/{virtual_partitions/distributors/consistent.rb → consumer_groups/jobs/eofed_non_blocking.rb} +16 -14
  69. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +64 -0
  70. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/periodic_non_blocking.rb +16 -11
  71. data/lib/karafka/pro/processing/{jobs → consumer_groups/jobs}/revoked_non_blocking.rb +19 -15
  72. data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +95 -0
  73. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +66 -0
  74. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +154 -0
  75. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +68 -0
  76. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +102 -0
  77. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +115 -0
  78. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +96 -0
  79. data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +98 -0
  80. data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +90 -0
  81. data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +154 -0
  82. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +93 -0
  83. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +99 -0
  84. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +92 -0
  85. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +90 -0
  86. data/lib/karafka/pro/processing/{strategies/aj/dlq_ftr_lrj_mom.rb → consumer_groups/strategies/aj/dlq_lrj_mom.rb} +37 -39
  87. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +90 -0
  88. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +84 -0
  89. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +89 -0
  90. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_lrj_mom.rb +20 -15
  91. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +91 -0
  92. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/aj/ftr_mom.rb +20 -15
  93. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +80 -0
  94. data/lib/karafka/pro/processing/{strategies/mom/default.rb → consumer_groups/strategies/aj/lrj_mom.rb} +18 -22
  95. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +106 -0
  96. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +58 -0
  97. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +74 -0
  98. data/lib/karafka/pro/processing/{strategies/lrj/vp.rb → consumer_groups/strategies/base.rb} +9 -14
  99. data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +421 -0
  100. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +285 -0
  101. data/lib/karafka/pro/processing/{strategies/dlq/lrj.rb → consumer_groups/strategies/dlq/ftr.rb} +30 -29
  102. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +95 -0
  103. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +97 -0
  104. data/lib/karafka/pro/processing/{executor.rb → consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb} +26 -15
  105. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +63 -0
  106. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +97 -0
  107. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +63 -0
  108. data/lib/karafka/pro/{routing/features/patterns/patterns.rb → processing/consumer_groups/strategies/dlq/ftr_vp.rb} +22 -12
  109. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +83 -0
  110. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +100 -0
  111. data/lib/karafka/pro/processing/{strategies → consumer_groups/strategies}/dlq/lrj_mom_vp.rb +18 -13
  112. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +61 -0
  113. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +96 -0
  114. data/lib/karafka/pro/processing/{strategies/lrj → consumer_groups/strategies/dlq}/mom_vp.rb +19 -15
  115. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +62 -0
  116. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +146 -0
  117. data/lib/karafka/pro/processing/{strategies/mom/ftr.rb → consumer_groups/strategies/ftr/vp.rb} +20 -28
  118. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +119 -0
  119. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +94 -0
  120. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +92 -0
  121. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +62 -0
  122. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +61 -0
  123. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +101 -0
  124. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +60 -0
  125. data/lib/karafka/pro/processing/{strategies/mom → consumer_groups/strategies/lrj}/vp.rb +18 -12
  126. data/lib/karafka/pro/processing/{strategies/aj/mom_vp.rb → consumer_groups/strategies/mom/default.rb} +22 -23
  127. data/lib/karafka/pro/processing/{strategies/aj/ftr_mom_vp.rb → consumer_groups/strategies/mom/ftr.rb} +28 -28
  128. data/lib/karafka/pro/processing/{virtual_partitions/distributors/base.rb → consumer_groups/strategies/mom/ftr_vp.rb} +19 -14
  129. data/lib/karafka/pro/processing/{strategies/aj/mom.rb → consumer_groups/strategies/mom/vp.rb} +16 -12
  130. data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +197 -0
  131. data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +106 -0
  132. data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +73 -0
  133. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +82 -0
  134. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +59 -0
  135. data/lib/karafka/pro/processing/{strategies/dlq/ftr.rb → consumer_groups/virtual_partitions/distributors/consistent.rb} +18 -33
  136. data/lib/karafka/pro/processing/filters/base.rb +3 -61
  137. data/lib/karafka/pro/processing/partitioner.rb +2 -57
  138. data/lib/karafka/pro/processing/schedulers/base.rb +10 -6
  139. data/lib/karafka/pro/processing/schedulers/default.rb +6 -5
  140. data/lib/karafka/pro/recurring_tasks/executor.rb +1 -2
  141. data/lib/karafka/pro/routing/features/{active_job → consumer_groups/active_job}/builder.rb +20 -18
  142. data/lib/karafka/pro/routing/features/{inline_insights/config.rb → consumer_groups/active_job.rb} +5 -9
  143. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/config.rb +53 -0
  144. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/contracts/topic.rb +91 -0
  145. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator/topic.rb +90 -0
  146. data/lib/karafka/pro/routing/features/consumer_groups/adaptive_iterator.rb +50 -0
  147. data/lib/karafka/pro/routing/features/{patterns/contracts/consumer_group.rb → consumer_groups/dead_letter_queue/contracts/topic.rb} +25 -30
  148. data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue/topic.rb +70 -0
  149. data/lib/karafka/pro/routing/features/consumer_groups/dead_letter_queue.rb +46 -0
  150. data/lib/karafka/pro/routing/features/{direct_assignments → consumer_groups/delaying}/config.rb +6 -4
  151. data/lib/karafka/pro/routing/features/{patterns/contracts/pattern.rb → consumer_groups/delaying/contracts/topic.rb} +13 -16
  152. data/lib/karafka/pro/routing/features/consumer_groups/delaying/topic.rb +85 -0
  153. data/lib/karafka/pro/routing/features/{adaptive_iterator/config.rb → consumer_groups/delaying.rb} +8 -11
  154. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/config.rb +46 -0
  155. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/consumer_group.rb +68 -0
  156. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/contracts/topic.rb +125 -0
  157. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +97 -0
  158. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/topic.rb +97 -0
  159. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments.rb +44 -0
  160. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/config.rb +51 -0
  161. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/contracts/topic.rb +58 -0
  162. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights/topic.rb +80 -0
  163. data/lib/karafka/pro/routing/features/consumer_groups/inline_insights.rb +45 -0
  164. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/config.rb +47 -0
  165. data/lib/karafka/pro/routing/features/{multiplexing/patches/contracts/consumer_group.rb → consumer_groups/long_running_job/contracts/topic.rb} +13 -15
  166. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job/topic.rb +72 -0
  167. data/lib/karafka/pro/routing/features/{long_running_job.rb → consumer_groups/long_running_job.rb} +6 -4
  168. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/config.rb +58 -0
  169. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/routing.rb +83 -0
  170. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/contracts/topic.rb +148 -0
  171. data/lib/karafka/pro/routing/features/{delaying/contracts/topic.rb → consumer_groups/multiplexing/patches/contracts/consumer_group.rb} +19 -14
  172. data/lib/karafka/pro/routing/features/{multiplexing/subscription_group.rb → consumer_groups/multiplexing/proxy.rb} +17 -23
  173. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/subscription_group.rb +68 -0
  174. data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/multiplexing}/subscription_groups_builder.rb +16 -14
  175. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing.rb +85 -0
  176. data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job/topic.rb +51 -0
  177. data/lib/karafka/pro/routing/features/{non_blocking_job.rb → consumer_groups/non_blocking_job.rb} +15 -13
  178. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/config.rb +52 -0
  179. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/contracts/topic.rb +59 -0
  180. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +93 -0
  181. data/lib/karafka/pro/routing/features/{offset_metadata.rb → consumer_groups/offset_metadata.rb} +16 -14
  182. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/builder.rb +74 -0
  183. data/lib/karafka/pro/routing/features/{multiplexing → consumer_groups/parallel_segments}/config.rb +13 -15
  184. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +110 -0
  185. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/contracts/consumer_group.rb +74 -0
  186. data/lib/karafka/pro/routing/features/{parallel_segments → consumer_groups/parallel_segments}/topic.rb +24 -22
  187. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments.rb +51 -0
  188. data/lib/karafka/pro/routing/features/{patterns → consumer_groups/patterns}/builder.rb +15 -13
  189. data/lib/karafka/pro/routing/features/{offset_metadata/contracts/topic.rb → consumer_groups/patterns/config.rb} +28 -13
  190. data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +91 -0
  191. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/consumer_group.rb +83 -0
  192. data/lib/karafka/pro/routing/features/{parallel_segments.rb → consumer_groups/patterns/contracts/pattern.rb} +24 -10
  193. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/topic.rb +58 -0
  194. data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +98 -0
  195. data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +114 -0
  196. data/lib/karafka/pro/routing/features/{recurring_tasks/contracts/topic.rb → consumer_groups/patterns/patterns.rb} +12 -13
  197. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topic.rb +78 -0
  198. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +72 -0
  199. data/lib/karafka/pro/routing/features/consumer_groups/patterns.rb +52 -0
  200. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/config.rb +56 -0
  201. data/lib/karafka/pro/routing/features/{direct_assignments/contracts/consumer_group.rb → consumer_groups/periodic_job/contracts/topic.rb} +17 -22
  202. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +122 -0
  203. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job.rb +46 -0
  204. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +150 -0
  205. data/lib/karafka/pro/routing/features/{swarm → consumer_groups/recurring_tasks}/config.rb +7 -8
  206. data/lib/karafka/pro/routing/features/{inline_insights → consumer_groups/recurring_tasks}/contracts/topic.rb +14 -13
  207. data/lib/karafka/pro/routing/features/{scheduled_messages → consumer_groups/recurring_tasks}/proxy.rb +6 -4
  208. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/topic.rb +72 -0
  209. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks.rb +44 -0
  210. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +154 -0
  211. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/config.rb +47 -0
  212. data/lib/karafka/pro/routing/features/{long_running_job → consumer_groups/scheduled_messages}/contracts/topic.rb +14 -12
  213. data/lib/karafka/pro/routing/features/{delaying/config.rb → consumer_groups/scheduled_messages/proxy.rb} +6 -4
  214. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +72 -0
  215. data/lib/karafka/pro/routing/features/{recurring_tasks/proxy.rb → consumer_groups/scheduled_messages.rb} +3 -4
  216. data/lib/karafka/pro/routing/features/{non_blocking_job/topic.rb → consumer_groups/swarm/config.rb} +9 -8
  217. data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/routing.rb +94 -0
  218. data/lib/karafka/pro/routing/features/consumer_groups/swarm/contracts/topic.rb +95 -0
  219. data/lib/karafka/pro/routing/features/consumer_groups/swarm/topic.rb +105 -0
  220. data/lib/karafka/pro/routing/features/consumer_groups/swarm.rb +58 -0
  221. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/config.rb +69 -0
  222. data/lib/karafka/pro/routing/features/{parallel_segments/contracts/consumer_group.rb → consumer_groups/virtual_partitions/contracts/topic.rb} +21 -18
  223. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +101 -0
  224. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions.rb +46 -0
  225. data/lib/karafka/pro/routing/features/{scheduled_messages.rb → consumer_groups.rb} +3 -2
  226. data/lib/karafka/pro/routing/features/expiring/topic.rb +4 -4
  227. data/lib/karafka/pro/routing/features/filtering/topic.rb +3 -3
  228. data/lib/karafka/pro/routing/features/pausing/topic.rb +3 -3
  229. data/lib/karafka/pro/routing/features/throttling/topic.rb +4 -4
  230. data/lib/karafka/pro/setup/defaults_injector.rb +70 -0
  231. data/lib/karafka/pro/swarm/liveness_listener.rb +22 -10
  232. data/lib/karafka/processing/consumer_groups/coordinator.rb +221 -0
  233. data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +69 -0
  234. data/lib/karafka/processing/consumer_groups/executor.rb +220 -0
  235. data/lib/karafka/processing/consumer_groups/executors_buffer.rb +94 -0
  236. data/lib/karafka/processing/consumer_groups/expansions_selector.rb +26 -0
  237. data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +47 -0
  238. data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +23 -0
  239. data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +132 -0
  240. data/lib/karafka/processing/consumer_groups/jobs/consume.rb +52 -0
  241. data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +34 -0
  242. data/lib/karafka/processing/consumer_groups/jobs/idle.rb +33 -0
  243. data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +34 -0
  244. data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +32 -0
  245. data/lib/karafka/processing/consumer_groups/jobs_builder.rb +36 -0
  246. data/lib/karafka/processing/consumer_groups/partitioner.rb +28 -0
  247. data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +48 -0
  248. data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +25 -0
  249. data/lib/karafka/processing/consumer_groups/strategies/base.rb +65 -0
  250. data/lib/karafka/processing/consumer_groups/strategies/default.rb +218 -0
  251. data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +157 -0
  252. data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +72 -0
  253. data/lib/karafka/processing/consumer_groups/strategies/mom.rb +33 -0
  254. data/lib/karafka/processing/consumer_groups/strategy_selector.rb +53 -0
  255. data/lib/karafka/processing/coordinator.rb +4 -211
  256. data/lib/karafka/processing/coordinators_buffer.rb +4 -59
  257. data/lib/karafka/processing/jobs_queue.rb +12 -4
  258. data/lib/karafka/processing/partitioner.rb +4 -18
  259. data/lib/karafka/processing/schedulers/default.rb +2 -1
  260. data/lib/karafka/processing/strategy_selector.rb +4 -42
  261. data/lib/karafka/processing/worker.rb +8 -4
  262. data/lib/karafka/processing/workers_pool.rb +158 -0
  263. data/lib/karafka/routing/builder.rb +12 -12
  264. data/lib/karafka/routing/contracts/routing.rb +3 -4
  265. data/lib/karafka/routing/features/base/expander.rb +5 -5
  266. data/lib/karafka/routing/features/consumer_groups/active_job/builder.rb +35 -0
  267. data/lib/karafka/routing/features/consumer_groups/active_job/config.rb +17 -0
  268. data/lib/karafka/routing/features/consumer_groups/active_job/contracts/topic.rb +44 -0
  269. data/lib/karafka/routing/features/consumer_groups/active_job/proxy.rb +16 -0
  270. data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +50 -0
  271. data/lib/karafka/routing/features/consumer_groups/active_job.rb +15 -0
  272. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/config.rb +39 -0
  273. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/contracts/topic.rb +58 -0
  274. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue/topic.rb +76 -0
  275. data/lib/karafka/routing/features/consumer_groups/dead_letter_queue.rb +18 -0
  276. data/lib/karafka/routing/features/consumer_groups/eofed/config.rb +17 -0
  277. data/lib/karafka/routing/features/consumer_groups/eofed/contracts/topic.rb +39 -0
  278. data/lib/karafka/routing/features/consumer_groups/eofed/topic.rb +42 -0
  279. data/lib/karafka/routing/features/consumer_groups/eofed.rb +16 -0
  280. data/lib/karafka/routing/features/consumer_groups/inline_insights/config.rb +17 -0
  281. data/lib/karafka/routing/features/consumer_groups/inline_insights/contracts/topic.rb +27 -0
  282. data/lib/karafka/routing/features/consumer_groups/inline_insights/topic.rb +42 -0
  283. data/lib/karafka/routing/features/consumer_groups/inline_insights.rb +42 -0
  284. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/config.rb +17 -0
  285. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/contracts/topic.rb +27 -0
  286. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +46 -0
  287. data/lib/karafka/routing/features/consumer_groups/manual_offset_management.rb +20 -0
  288. data/lib/karafka/routing/features/consumer_groups.rb +12 -0
  289. data/lib/karafka/routing/features/declaratives/contracts/topic.rb +4 -19
  290. data/lib/karafka/routing/features/declaratives/topic.rb +30 -14
  291. data/lib/karafka/routing/features/deserializers/topic.rb +3 -3
  292. data/lib/karafka/routing/router.rb +2 -2
  293. data/lib/karafka/routing/subscription_group.rb +18 -9
  294. data/lib/karafka/routing/topic.rb +25 -11
  295. data/lib/karafka/runner.rb +17 -17
  296. data/lib/karafka/server.rb +28 -6
  297. data/lib/karafka/setup/attributes_map.rb +2 -0
  298. data/lib/karafka/setup/config.rb +64 -15
  299. data/lib/karafka/setup/config_proxy.rb +1 -2
  300. data/lib/karafka/setup/contracts/config.rb +28 -8
  301. data/lib/karafka/setup/defaults_injector.rb +10 -0
  302. data/lib/karafka/status.rb +1 -2
  303. data/lib/karafka/swarm/liveness_listener.rb +7 -0
  304. data/lib/karafka/swarm/manager.rb +7 -7
  305. data/lib/karafka/swarm/node.rb +8 -0
  306. data/lib/karafka/swarm/supervisor.rb +9 -1
  307. data/lib/karafka/templates/karafka.rb.erb +11 -5
  308. data/lib/karafka/version.rb +1 -1
  309. metadata +237 -224
  310. data/lib/karafka/connection/rebalance_manager.rb +0 -116
  311. data/lib/karafka/instrumentation/callbacks/error.rb +0 -52
  312. data/lib/karafka/instrumentation/callbacks/rebalance.rb +0 -84
  313. data/lib/karafka/instrumentation/callbacks/statistics.rb +0 -55
  314. data/lib/karafka/pro/processing/adaptive_iterator/consumer.rb +0 -79
  315. data/lib/karafka/pro/processing/adaptive_iterator/tracker.rb +0 -92
  316. data/lib/karafka/pro/processing/collapser.rb +0 -79
  317. data/lib/karafka/pro/processing/coordinator.rb +0 -197
  318. data/lib/karafka/pro/processing/coordinators/errors_tracker.rb +0 -119
  319. data/lib/karafka/pro/processing/coordinators/filters_applier.rb +0 -152
  320. data/lib/karafka/pro/processing/coordinators/virtual_offset_manager.rb +0 -207
  321. data/lib/karafka/pro/processing/expansions_selector.rb +0 -52
  322. data/lib/karafka/pro/processing/filters/delayer.rb +0 -87
  323. data/lib/karafka/pro/processing/filters/inline_insights_delayer.rb +0 -95
  324. data/lib/karafka/pro/processing/filters/throttler.rb +0 -101
  325. data/lib/karafka/pro/processing/filters/virtual_limiter.rb +0 -74
  326. data/lib/karafka/pro/processing/jobs/eofed_non_blocking.rb +0 -51
  327. data/lib/karafka/pro/processing/jobs_builder.rb +0 -90
  328. data/lib/karafka/pro/processing/offset_metadata/consumer.rb +0 -61
  329. data/lib/karafka/pro/processing/offset_metadata/fetcher.rb +0 -149
  330. data/lib/karafka/pro/processing/offset_metadata/listener.rb +0 -63
  331. data/lib/karafka/pro/processing/parallel_segments/filters/base.rb +0 -98
  332. data/lib/karafka/pro/processing/parallel_segments/filters/default.rb +0 -110
  333. data/lib/karafka/pro/processing/parallel_segments/filters/mom.rb +0 -91
  334. data/lib/karafka/pro/processing/periodic_job/consumer.rb +0 -85
  335. data/lib/karafka/pro/processing/piping/consumer.rb +0 -149
  336. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_lrj_mom_vp.rb +0 -94
  337. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom.rb +0 -87
  338. data/lib/karafka/pro/processing/strategies/aj/dlq_ftr_mom_vp.rb +0 -85
  339. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom.rb +0 -81
  340. data/lib/karafka/pro/processing/strategies/aj/dlq_lrj_mom_vp.rb +0 -85
  341. data/lib/karafka/pro/processing/strategies/aj/dlq_mom.rb +0 -79
  342. data/lib/karafka/pro/processing/strategies/aj/dlq_mom_vp.rb +0 -84
  343. data/lib/karafka/pro/processing/strategies/aj/ftr_lrj_mom_vp.rb +0 -86
  344. data/lib/karafka/pro/processing/strategies/aj/lrj_mom.rb +0 -54
  345. data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +0 -101
  346. data/lib/karafka/pro/processing/strategies/base.rb +0 -43
  347. data/lib/karafka/pro/processing/strategies/default.rb +0 -416
  348. data/lib/karafka/pro/processing/strategies/dlq/default.rb +0 -280
  349. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj.rb +0 -90
  350. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom.rb +0 -92
  351. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_mom_vp.rb +0 -60
  352. data/lib/karafka/pro/processing/strategies/dlq/ftr_lrj_vp.rb +0 -58
  353. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom.rb +0 -92
  354. data/lib/karafka/pro/processing/strategies/dlq/ftr_mom_vp.rb +0 -58
  355. data/lib/karafka/pro/processing/strategies/dlq/ftr_vp.rb +0 -57
  356. data/lib/karafka/pro/processing/strategies/dlq/lrj_mom.rb +0 -95
  357. data/lib/karafka/pro/processing/strategies/dlq/lrj_vp.rb +0 -56
  358. data/lib/karafka/pro/processing/strategies/dlq/mom.rb +0 -91
  359. data/lib/karafka/pro/processing/strategies/dlq/mom_vp.rb +0 -54
  360. data/lib/karafka/pro/processing/strategies/dlq/vp.rb +0 -57
  361. data/lib/karafka/pro/processing/strategies/ftr/default.rb +0 -141
  362. data/lib/karafka/pro/processing/strategies/ftr/vp.rb +0 -57
  363. data/lib/karafka/pro/processing/strategies/lrj/default.rb +0 -114
  364. data/lib/karafka/pro/processing/strategies/lrj/ftr.rb +0 -89
  365. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom.rb +0 -87
  366. data/lib/karafka/pro/processing/strategies/lrj/ftr_mom_vp.rb +0 -57
  367. data/lib/karafka/pro/processing/strategies/lrj/ftr_vp.rb +0 -56
  368. data/lib/karafka/pro/processing/strategies/lrj/mom.rb +0 -96
  369. data/lib/karafka/pro/processing/strategies/mom/ftr_vp.rb +0 -54
  370. data/lib/karafka/pro/processing/strategies/vp/default.rb +0 -192
  371. data/lib/karafka/pro/processing/strategies.rb +0 -39
  372. data/lib/karafka/pro/processing/strategy_selector.rb +0 -102
  373. data/lib/karafka/pro/processing/subscription_groups_coordinator.rb +0 -68
  374. data/lib/karafka/pro/processing/virtual_partitions/distributors/balanced.rb +0 -77
  375. data/lib/karafka/pro/routing/features/active_job.rb +0 -43
  376. data/lib/karafka/pro/routing/features/adaptive_iterator/contracts/topic.rb +0 -89
  377. data/lib/karafka/pro/routing/features/adaptive_iterator/topic.rb +0 -88
  378. data/lib/karafka/pro/routing/features/adaptive_iterator.rb +0 -48
  379. data/lib/karafka/pro/routing/features/dead_letter_queue/contracts/topic.rb +0 -74
  380. data/lib/karafka/pro/routing/features/dead_letter_queue/topic.rb +0 -68
  381. data/lib/karafka/pro/routing/features/dead_letter_queue.rb +0 -44
  382. data/lib/karafka/pro/routing/features/delaying/topic.rb +0 -83
  383. data/lib/karafka/pro/routing/features/delaying.rb +0 -46
  384. data/lib/karafka/pro/routing/features/direct_assignments/contracts/topic.rb +0 -123
  385. data/lib/karafka/pro/routing/features/direct_assignments/subscription_group.rb +0 -95
  386. data/lib/karafka/pro/routing/features/direct_assignments/topic.rb +0 -95
  387. data/lib/karafka/pro/routing/features/direct_assignments.rb +0 -42
  388. data/lib/karafka/pro/routing/features/inline_insights/topic.rb +0 -78
  389. data/lib/karafka/pro/routing/features/inline_insights.rb +0 -43
  390. data/lib/karafka/pro/routing/features/long_running_job/config.rb +0 -45
  391. data/lib/karafka/pro/routing/features/long_running_job/topic.rb +0 -70
  392. data/lib/karafka/pro/routing/features/multiplexing/contracts/routing.rb +0 -81
  393. data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +0 -146
  394. data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +0 -58
  395. data/lib/karafka/pro/routing/features/multiplexing.rb +0 -83
  396. data/lib/karafka/pro/routing/features/offset_metadata/config.rb +0 -50
  397. data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +0 -91
  398. data/lib/karafka/pro/routing/features/parallel_segments/builder.rb +0 -72
  399. data/lib/karafka/pro/routing/features/parallel_segments/config.rb +0 -52
  400. data/lib/karafka/pro/routing/features/parallel_segments/consumer_group.rb +0 -108
  401. data/lib/karafka/pro/routing/features/patterns/config.rb +0 -71
  402. data/lib/karafka/pro/routing/features/patterns/consumer_group.rb +0 -89
  403. data/lib/karafka/pro/routing/features/patterns/contracts/topic.rb +0 -56
  404. data/lib/karafka/pro/routing/features/patterns/detector.rb +0 -96
  405. data/lib/karafka/pro/routing/features/patterns/pattern.rb +0 -112
  406. data/lib/karafka/pro/routing/features/patterns/topic.rb +0 -76
  407. data/lib/karafka/pro/routing/features/patterns/topics.rb +0 -70
  408. data/lib/karafka/pro/routing/features/patterns.rb +0 -50
  409. data/lib/karafka/pro/routing/features/periodic_job/config.rb +0 -54
  410. data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +0 -59
  411. data/lib/karafka/pro/routing/features/periodic_job/topic.rb +0 -120
  412. data/lib/karafka/pro/routing/features/periodic_job.rb +0 -44
  413. data/lib/karafka/pro/routing/features/recurring_tasks/builder.rb +0 -148
  414. data/lib/karafka/pro/routing/features/recurring_tasks/config.rb +0 -45
  415. data/lib/karafka/pro/routing/features/recurring_tasks/topic.rb +0 -70
  416. data/lib/karafka/pro/routing/features/recurring_tasks.rb +0 -42
  417. data/lib/karafka/pro/routing/features/scheduled_messages/builder.rb +0 -152
  418. data/lib/karafka/pro/routing/features/scheduled_messages/config.rb +0 -45
  419. data/lib/karafka/pro/routing/features/scheduled_messages/contracts/topic.rb +0 -55
  420. data/lib/karafka/pro/routing/features/scheduled_messages/topic.rb +0 -70
  421. data/lib/karafka/pro/routing/features/swarm/contracts/routing.rb +0 -92
  422. data/lib/karafka/pro/routing/features/swarm/contracts/topic.rb +0 -93
  423. data/lib/karafka/pro/routing/features/swarm/topic.rb +0 -103
  424. data/lib/karafka/pro/routing/features/swarm.rb +0 -56
  425. data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +0 -67
  426. data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +0 -73
  427. data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +0 -99
  428. data/lib/karafka/pro/routing/features/virtual_partitions.rb +0 -44
  429. data/lib/karafka/processing/executor.rb +0 -216
  430. data/lib/karafka/processing/executors_buffer.rb +0 -90
  431. data/lib/karafka/processing/expansions_selector.rb +0 -22
  432. data/lib/karafka/processing/inline_insights/consumer.rb +0 -43
  433. data/lib/karafka/processing/inline_insights/listener.rb +0 -19
  434. data/lib/karafka/processing/inline_insights/tracker.rb +0 -129
  435. data/lib/karafka/processing/jobs/consume.rb +0 -47
  436. data/lib/karafka/processing/jobs/eofed.rb +0 -29
  437. data/lib/karafka/processing/jobs/idle.rb +0 -31
  438. data/lib/karafka/processing/jobs/revoked.rb +0 -29
  439. data/lib/karafka/processing/jobs/shutdown.rb +0 -30
  440. data/lib/karafka/processing/jobs_builder.rb +0 -34
  441. data/lib/karafka/processing/strategies/aj_dlq_mom.rb +0 -44
  442. data/lib/karafka/processing/strategies/aj_mom.rb +0 -21
  443. data/lib/karafka/processing/strategies/base.rb +0 -61
  444. data/lib/karafka/processing/strategies/default.rb +0 -214
  445. data/lib/karafka/processing/strategies/dlq.rb +0 -153
  446. data/lib/karafka/processing/strategies/dlq_mom.rb +0 -68
  447. data/lib/karafka/processing/strategies/mom.rb +0 -29
  448. data/lib/karafka/processing/workers_batch.rb +0 -29
  449. data/lib/karafka/routing/features/active_job/builder.rb +0 -33
  450. data/lib/karafka/routing/features/active_job/config.rb +0 -15
  451. data/lib/karafka/routing/features/active_job/contracts/topic.rb +0 -42
  452. data/lib/karafka/routing/features/active_job/proxy.rb +0 -14
  453. data/lib/karafka/routing/features/active_job/topic.rb +0 -48
  454. data/lib/karafka/routing/features/active_job.rb +0 -13
  455. data/lib/karafka/routing/features/dead_letter_queue/config.rb +0 -37
  456. data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +0 -56
  457. data/lib/karafka/routing/features/dead_letter_queue/topic.rb +0 -74
  458. data/lib/karafka/routing/features/dead_letter_queue.rb +0 -16
  459. data/lib/karafka/routing/features/declaratives/config.rb +0 -18
  460. data/lib/karafka/routing/features/eofed/config.rb +0 -15
  461. data/lib/karafka/routing/features/eofed/contracts/topic.rb +0 -37
  462. data/lib/karafka/routing/features/eofed/topic.rb +0 -40
  463. data/lib/karafka/routing/features/eofed.rb +0 -14
  464. data/lib/karafka/routing/features/inline_insights/config.rb +0 -15
  465. data/lib/karafka/routing/features/inline_insights/contracts/topic.rb +0 -25
  466. data/lib/karafka/routing/features/inline_insights/topic.rb +0 -40
  467. data/lib/karafka/routing/features/inline_insights.rb +0 -40
  468. data/lib/karafka/routing/features/manual_offset_management/config.rb +0 -15
  469. data/lib/karafka/routing/features/manual_offset_management/contracts/topic.rb +0 -25
  470. data/lib/karafka/routing/features/manual_offset_management/topic.rb +0 -44
  471. data/lib/karafka/routing/features/manual_offset_management.rb +0 -18
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Processing
5
- module Strategies
6
- # When using dead letter queue, processing won't stop after defined number of retries
7
- # upon encountering non-critical errors but the messages that error will be moved to a
8
- # separate topic with their payload and metadata, so they can be handled differently.
9
- module Dlq
10
- include Default
11
-
12
- # Apply strategy when only dead letter queue is turned on
13
- FEATURES = %i[
14
- dead_letter_queue
15
- ].freeze
16
-
17
- # Override of the standard `#mark_as_consumed` in order to handle the pause tracker
18
- # reset in case DLQ is marked as fully independent. When DLQ is marked independent,
19
- # any offset marking causes the pause count tracker to reset. This is useful when
20
- # the error is not due to the collective batch operations state but due to intermediate
21
- # "crawling" errors that move with it
22
- #
23
- # @see `Strategies::Default#mark_as_consumed` for more details
24
- # @param message [Messages::Message]
25
- def mark_as_consumed(message)
26
- # If we are not retrying pause count is already 0, no need to try to reset the state
27
- return super unless retrying?
28
- # If we do not use independent marking on DLQ, we just mark as consumed
29
- return super unless topic.dead_letter_queue.independent?
30
- # If we were not able to mark no need to reset
31
- return false unless super
32
-
33
- coordinator.pause_tracker.reset
34
-
35
- true
36
- end
37
-
38
- # Override of the standard `#mark_as_consumed!`. Resets the pause tracker count in case
39
- # DLQ was configured with the `independent` flag.
40
- #
41
- # @see `Strategies::Default#mark_as_consumed!` for more details
42
- # @param message [Messages::Message]
43
- def mark_as_consumed!(message)
44
- return super unless retrying?
45
- return super unless topic.dead_letter_queue.independent?
46
- return false unless super
47
-
48
- coordinator.pause_tracker.reset
49
-
50
- true
51
- end
52
-
53
- # When manual offset management is on, we do not mark anything as consumed automatically
54
- # and we rely on the user to figure things out
55
- def handle_after_consume
56
- return if revoked?
57
-
58
- if coordinator.success?
59
- coordinator.pause_tracker.reset
60
-
61
- return if coordinator.manual_pause?
62
-
63
- mark_as_consumed(messages.last)
64
- elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
65
- retry_after_pause
66
- # If we've reached number of retries that we could, we need to skip the first message
67
- # that was not marked as consumed, pause and continue, while also moving this message
68
- # to the dead topic
69
- else
70
- # We reset the pause to indicate we will now consider it as "ok".
71
- coordinator.pause_tracker.reset
72
-
73
- skippable_message, = find_skippable_message
74
-
75
- # Send skippable message to the dql topic
76
- dispatch_to_dlq(skippable_message)
77
-
78
- # We mark the broken message as consumed and move on
79
- if mark_after_dispatch?
80
- mark_dispatched_to_dlq(skippable_message)
81
-
82
- return if revoked?
83
- else
84
- self.seek_offset = skippable_message.offset + 1
85
- end
86
-
87
- # We pause to backoff once just in case.
88
- pause(seek_offset, nil, false)
89
- end
90
- end
91
-
92
- # Finds the message may want to skip (all, starting from first)
93
- # @private
94
- # @return [Array<Karafka::Messages::Message, Boolean>] message we may want to skip and
95
- # information if this message was from marked offset or figured out via mom flow
96
- def find_skippable_message
97
- skippable_message = messages.raw.find do |msg|
98
- coordinator.marked? && msg.offset == seek_offset
99
- end
100
-
101
- # If we don't have the message matching the last comitted offset, it means that
102
- # user operates with manual offsets and we're beyond the batch in which things
103
- # broke for the first time. Then we skip the first (as no markings) and we
104
- # move on one by one.
105
- skippable_message ? [skippable_message, true] : [messages.first, false]
106
- end
107
-
108
- # Moves the broken message into a separate queue defined via the settings
109
- # @private
110
- # @param skippable_message [Karafka::Messages::Message] message we are skipping that also
111
- # should go to the dlq topic
112
- def dispatch_to_dlq(skippable_message)
113
- producer.public_send(
114
- topic.dead_letter_queue.dispatch_method,
115
- topic: topic.dead_letter_queue.topic,
116
- payload: skippable_message.raw_payload
117
- )
118
-
119
- # Notify about dispatch on the events bus
120
- monitor.instrument(
121
- "dead_letter_queue.dispatched",
122
- caller: self,
123
- message: skippable_message
124
- )
125
- end
126
-
127
- # @return [Boolean] should we mark given message as consumed after dispatch. For default
128
- # non MOM strategies if user did not explicitly tell us not to, we mark it. Default is
129
- # `nil`, which means `true` in this case. If user provided alternative value, we go
130
- # with it.
131
- def mark_after_dispatch?
132
- return true if topic.dead_letter_queue.mark_after_dispatch.nil?
133
-
134
- topic.dead_letter_queue.mark_after_dispatch
135
- end
136
-
137
- # Marks message that went to DLQ (if applicable) based on the requested method
138
- # @param skippable_message [Karafka::Messages::Message]
139
- def mark_dispatched_to_dlq(skippable_message)
140
- case topic.dead_letter_queue.marking_method
141
- when :mark_as_consumed
142
- mark_as_consumed(skippable_message)
143
- when :mark_as_consumed!
144
- mark_as_consumed!(skippable_message)
145
- else
146
- # This should never happen. Bug if encountered. Please report
147
- raise Karafka::Errors::UnsupportedCaseError
148
- end
149
- end
150
- end
151
- end
152
- end
153
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Processing
5
- module Strategies
6
- # Same as pure dead letter queue but we do not marked failed message as consumed
7
- module DlqMom
8
- include Dlq
9
-
10
- # Apply strategy when dlq is on with manual offset management
11
- FEATURES = %i[
12
- dead_letter_queue
13
- manual_offset_management
14
- ].freeze
15
-
16
- # When manual offset management is on, we do not mark anything as consumed automatically
17
- # and we rely on the user to figure things out
18
- def handle_after_consume
19
- return if revoked?
20
-
21
- if coordinator.success?
22
- coordinator.pause_tracker.reset
23
- elsif coordinator.pause_tracker.attempt <= topic.dead_letter_queue.max_retries
24
- retry_after_pause
25
- # If we've reached number of retries that we could, we need to skip the first message
26
- # that was not marked as consumed, pause and continue, while also moving this message
27
- # to the dead topic
28
- else
29
- # We reset the pause to indicate we will now consider it as "ok".
30
- coordinator.pause_tracker.reset
31
-
32
- skippable_message, = find_skippable_message
33
-
34
- dispatch_to_dlq(skippable_message)
35
-
36
- # We mark the broken message as consumed and move on
37
- if mark_after_dispatch?
38
- mark_dispatched_to_dlq(skippable_message)
39
-
40
- return if revoked?
41
- else
42
- # Save the next offset we want to go with after moving given message to DLQ
43
- # Without this, we would not be able to move forward and we would end up
44
- # in an infinite loop trying to un-pause from the message we've already processed
45
- # Of course, since it's a MoM a rebalance or kill, will move it back as no
46
- # offsets are being committed
47
- self.seek_offset = skippable_message.offset + 1
48
- end
49
-
50
- pause(seek_offset, nil, false)
51
- end
52
- end
53
-
54
- # @return [Boolean] should we mark given message as consumed after dispatch. For
55
- # MOM strategies if user did not explicitly tell us to mark, we do not mark. Default is
56
- # `nil`, which means `false` in this case. If user provided alternative value, we go
57
- # with it.
58
- #
59
- # @note Please note, this is the opposite behavior than in case of AOM strategies.
60
- def mark_after_dispatch?
61
- return false if topic.dead_letter_queue.mark_after_dispatch.nil?
62
-
63
- topic.dead_letter_queue.mark_after_dispatch
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Processing
5
- module Strategies
6
- # When using manual offset management, we do not mark as consumed after successful processing
7
- module Mom
8
- include Default
9
-
10
- # Apply strategy when only manual offset management is turned on
11
- FEATURES = %i[
12
- manual_offset_management
13
- ].freeze
14
-
15
- # When manual offset management is on, we do not mark anything as consumed automatically
16
- # and we rely on the user to figure things out
17
- def handle_after_consume
18
- return if revoked?
19
-
20
- if coordinator.success?
21
- coordinator.pause_tracker.reset
22
- else
23
- retry_after_pause
24
- end
25
- end
26
- end
27
- end
28
- end
29
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Processing
5
- # Abstraction layer around workers batch.
6
- class WorkersBatch
7
- include Enumerable
8
- include Helpers::ConfigImporter.new(
9
- concurrency: %i[concurrency]
10
- )
11
-
12
- # @param jobs_queue [JobsQueue]
13
- # @return [WorkersBatch]
14
- def initialize(jobs_queue)
15
- @batch = Array.new(concurrency) { Processing::Worker.new(jobs_queue) }
16
- end
17
-
18
- # Iterates over available workers and yields each worker
19
- def each(&)
20
- @batch.each(&)
21
- end
22
-
23
- # @return [Integer] number of workers in the batch
24
- def size
25
- @batch.size
26
- end
27
- end
28
- end
29
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class ActiveJob < Base
7
- # Routing extensions for ActiveJob
8
- module Builder
9
- # This method simplifies routes definition for ActiveJob topics / queues by
10
- # auto-injecting the consumer class
11
- #
12
- # @param name [String, Symbol] name of the topic where ActiveJobs jobs should go
13
- # @param block [Proc] block that we can use for some extra configuration
14
- def active_job_topic(name, &block)
15
- topic(name) do
16
- consumer App.config.internal.active_job.consumer_class
17
- active_job true
18
-
19
- # This is handled by our custom ActiveJob consumer
20
- # Without this, default behaviour would cause messages to skip upon shutdown as the
21
- # offset would be committed for the last message
22
- manual_offset_management true
23
-
24
- next unless block
25
-
26
- instance_eval(&block)
27
- end
28
- end
29
- end
30
- end
31
- end
32
- end
33
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class ActiveJob < Base
7
- # Config for ActiveJob usage
8
- Config = Struct.new(
9
- :active,
10
- keyword_init: true
11
- ) { alias_method :active?, :active }
12
- end
13
- end
14
- end
15
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class ActiveJob < Base
7
- # This feature validation contracts
8
- module Contracts
9
- # Rules around using ActiveJob routing - basically you need to have ActiveJob available
10
- # in order to be able to use active job routing
11
- class Topic < Karafka::Contracts::Base
12
- configure do |config|
13
- config.error_messages = YAML.safe_load_file(
14
- File.join(Karafka.gem_root, "config", "locales", "errors.yml")
15
- ).fetch("en").fetch("validations").fetch("routing").fetch("topic")
16
- end
17
-
18
- virtual do |data, errors|
19
- next unless errors.empty?
20
- next unless data[:active_job][:active]
21
- # One should not define active job jobs without ActiveJob being available for usage
22
- next if Object.const_defined?("ActiveJob::Base")
23
-
24
- [[%i[consumer], :active_job_missing]]
25
- end
26
-
27
- # ActiveJob needs to always run with manual offset management
28
- # Automatic offset management cannot work with ActiveJob. Otherwise we could mark as
29
- # consumed jobs that did not run because of shutdown.
30
- virtual do |data, errors|
31
- next unless errors.empty?
32
- next unless data[:active_job][:active]
33
- next if data[:manual_offset_management][:active]
34
-
35
- [[%i[manual_offset_management], :must_be_enabled]]
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,14 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class ActiveJob < Base
7
- # Routing proxy extensions for ActiveJob
8
- module Proxy
9
- include Builder
10
- end
11
- end
12
- end
13
- end
14
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class ActiveJob < Base
7
- # Topic extensions to be able to check if given topic is ActiveJob topic
8
- #
9
- # @note ActiveJob topics do not have per-topic deserializer configuration. The deserializer
10
- # is configured globally via `config.internal.active_job.deserializer` because Rails
11
- # serializes jobs before dispatching them, requiring a consistent serialization format
12
- # across all ActiveJob topics. If you need custom serialization (e.g., Avro, Protobuf),
13
- # configure it once at the application level rather than per-topic.
14
- module Topic
15
- # This method calls the parent class initializer and then sets up the
16
- # extra instance variable to nil. The explicit initialization
17
- # to nil is included as an optimization for Ruby's object shapes system,
18
- # which improves memory layout and access performance.
19
- def initialize(...)
20
- super
21
- @active_job = nil
22
- end
23
-
24
- # @param active [Boolean] should this topic be considered one working with ActiveJob
25
- #
26
- # @note Since this feature supports only one setting (active), we can use the old API
27
- # where the boolean would be an argument
28
- def active_job(active = false)
29
- @active_job ||= Config.new(active: active)
30
- end
31
-
32
- # @return [Boolean] is this an ActiveJob topic
33
- def active_job?
34
- active_job.active?
35
- end
36
-
37
- # @return [Hash] topic with all its native configuration options plus active job
38
- # namespace settings
39
- def to_h
40
- super.merge(
41
- active_job: active_job.to_h
42
- ).freeze
43
- end
44
- end
45
- end
46
- end
47
- end
48
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- # Active-Job related components
7
- # @note We can load it always, despite someone not using ActiveJob as it just adds a method
8
- # to the routing, without actually breaking anything.
9
- class ActiveJob < Base
10
- end
11
- end
12
- end
13
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class DeadLetterQueue < Base
7
- # Config for dead letter queue feature
8
- Config = Struct.new(
9
- :active,
10
- # We add skip variants but in regular we support only `:one`
11
- :max_retries,
12
- # To what topic the skipped messages should be moved
13
- :topic,
14
- # Should retries be handled collectively on a batch or independently per message
15
- :independent,
16
- # Move to DLQ and mark as consumed in transactional mode (if applicable)
17
- :transactional,
18
- # Strategy to apply (if strategies supported)
19
- :strategy,
20
- # Should we use `#produce_sync` or `#produce_async`
21
- :dispatch_method,
22
- # Should we use `#mark_as_consumed` or `#mark_as_consumed!` (in flows that mark)
23
- :marking_method,
24
- # Should we mark as consumed after dispatch or not. True for most cases, except MOM where
25
- # it is on user to decide (false by default)
26
- :mark_after_dispatch,
27
- # Initialize with kwargs
28
- keyword_init: true
29
- ) do
30
- alias_method :active?, :active
31
- alias_method :independent?, :independent
32
- alias_method :transactional?, :transactional
33
- end
34
- end
35
- end
36
- end
37
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class DeadLetterQueue < Base
7
- # This feature validation contracts
8
- module Contracts
9
- # Rules around dead letter queue settings
10
- class Topic < Karafka::Contracts::Base
11
- configure do |config|
12
- config.error_messages = YAML.safe_load_file(
13
- File.join(Karafka.gem_root, "config", "locales", "errors.yml")
14
- ).fetch("en").fetch("validations").fetch("routing").fetch("topic")
15
- end
16
-
17
- nested :dead_letter_queue do
18
- required(:active) { |val| [true, false].include?(val) }
19
- required(:independent) { |val| [true, false].include?(val) }
20
- required(:max_retries) { |val| val.is_a?(Integer) && val >= 0 }
21
- required(:transactional) { |val| [true, false].include?(val) }
22
- required(:mark_after_dispatch) { |val| [true, false, nil].include?(val) }
23
-
24
- required(:dispatch_method) do |val|
25
- %i[produce_async produce_sync].include?(val)
26
- end
27
-
28
- required(:marking_method) do |val|
29
- %i[mark_as_consumed mark_as_consumed!].include?(val)
30
- end
31
- end
32
-
33
- # Validate topic name only if dlq is active
34
- virtual do |data, errors|
35
- next unless errors.empty?
36
-
37
- dead_letter_queue = data[:dead_letter_queue]
38
-
39
- next unless dead_letter_queue[:active]
40
-
41
- topic = dead_letter_queue[:topic]
42
- topic_regexp = Karafka::Contracts::TOPIC_REGEXP
43
-
44
- # When topic is set to false, it means we just want to skip dispatch on DLQ
45
- next if topic == false
46
- next if topic.is_a?(String) && topic_regexp.match?(topic)
47
- next if topic == :strategy
48
-
49
- [[%i[dead_letter_queue topic], :format]]
50
- end
51
- end
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class DeadLetterQueue < Base
7
- # DLQ topic extensions
8
- module Topic
9
- # After how many retries should be move data to DLQ
10
- DEFAULT_MAX_RETRIES = 3
11
-
12
- private_constant :DEFAULT_MAX_RETRIES
13
-
14
- # This method calls the parent class initializer and then sets up the
15
- # extra instance variable to nil. The explicit initialization
16
- # to nil is included as an optimization for Ruby's object shapes system,
17
- # which improves memory layout and access performance.
18
- def initialize(...)
19
- super
20
- @dead_letter_queue = nil
21
- end
22
-
23
- # @param max_retries [Integer] after how many retries should we move data to dlq
24
- # @param topic [String, false] where the messages should be moved if failing or false
25
- # if we do not want to move it anywhere and just skip
26
- # @param independent [Boolean] needs to be true in order for each marking as consumed
27
- # in a retry flow to reset the errors counter
28
- # @param transactional [Boolean] if applicable, should transaction be used to move
29
- # given message to the dead-letter topic and mark it as consumed.
30
- # @param dispatch_method [Symbol] `:produce_async` or `:produce_sync`. Describes
31
- # whether dispatch on dlq should be sync or async (async by default)
32
- # @param marking_method [Symbol] `:mark_as_consumed` or `:mark_as_consumed!`. Describes
33
- # whether marking on DLQ should be async or sync (async by default)
34
- # @param mark_after_dispatch [Boolean, nil] Should we mark after dispatch. `nil` means
35
- # that the default strategy approach to marking will be used. `true` or `false`
36
- # overwrites the default
37
- # @return [Config] defined config
38
- def dead_letter_queue(
39
- max_retries: DEFAULT_MAX_RETRIES,
40
- topic: nil,
41
- independent: false,
42
- transactional: true,
43
- dispatch_method: :produce_async,
44
- marking_method: :mark_as_consumed,
45
- mark_after_dispatch: nil
46
- )
47
- @dead_letter_queue ||= Config.new(
48
- active: !topic.nil?,
49
- max_retries: max_retries,
50
- topic: topic,
51
- independent: independent,
52
- transactional: transactional,
53
- dispatch_method: dispatch_method,
54
- marking_method: marking_method,
55
- mark_after_dispatch: mark_after_dispatch
56
- )
57
- end
58
-
59
- # @return [Boolean] is the dlq active or not
60
- def dead_letter_queue?
61
- dead_letter_queue.active?
62
- end
63
-
64
- # @return [Hash] topic with all its native configuration options plus dlq settings
65
- def to_h
66
- super.merge(
67
- dead_letter_queue: dead_letter_queue.to_h
68
- ).freeze
69
- end
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- # This feature allows to continue processing when encountering errors.
7
- # After certain number of retries, given messages will be moved to alternative topic,
8
- # unclogging processing.
9
- #
10
- # @note This feature has an expanded version in the Pro mode. We do not use a new feature
11
- # injection in Pro (topic settings)
12
- class DeadLetterQueue < Base
13
- end
14
- end
15
- end
16
- end
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class Declaratives < Base
7
- # Config for declarative topics feature
8
- Config = Struct.new(
9
- :active,
10
- :partitions,
11
- :replication_factor,
12
- :details,
13
- keyword_init: true
14
- ) { alias_method :active?, :active }
15
- end
16
- end
17
- end
18
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Karafka
4
- module Routing
5
- module Features
6
- class Eofed < Base
7
- # Config of this feature
8
- Config = Struct.new(
9
- :active,
10
- keyword_init: true
11
- ) { alias_method :active?, :active }
12
- end
13
- end
14
- end
15
- end