karafka 2.6.0.beta1 → 2.6.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -27
  3. data/certs/expired.txt +2 -0
  4. data/config/locales/errors.yml +5 -0
  5. data/karafka.gemspec +1 -1
  6. data/lib/active_job/queue_adapters/karafka_adapter.rb +1 -1
  7. data/lib/karafka/active_job/current_attributes/loading.rb +1 -1
  8. data/lib/karafka/active_job/current_attributes.rb +4 -2
  9. data/lib/karafka/active_job/dispatcher.rb +1 -2
  10. data/lib/karafka/admin/consumer_groups.rb +8 -2
  11. data/lib/karafka/admin/replication.rb +6 -3
  12. data/lib/karafka/admin/topics.rb +32 -12
  13. data/lib/karafka/admin.rb +155 -59
  14. data/lib/karafka/app.rb +1 -1
  15. data/lib/karafka/base_consumer.rb +33 -5
  16. data/lib/karafka/cli/console.rb +0 -1
  17. data/lib/karafka/cli/help.rb +0 -1
  18. data/lib/karafka/cli/info.rb +0 -1
  19. data/lib/karafka/cli/install.rb +0 -1
  20. data/lib/karafka/cli/server.rb +0 -1
  21. data/lib/karafka/cli/swarm.rb +0 -1
  22. data/lib/karafka/cli.rb +2 -2
  23. data/lib/karafka/connection/client.rb +44 -7
  24. data/lib/karafka/connection/listener.rb +3 -3
  25. data/lib/karafka/connection/manager.rb +0 -1
  26. data/lib/karafka/connection/pauses_manager.rb +17 -0
  27. data/lib/karafka/connection/proxy.rb +45 -0
  28. data/lib/karafka/connection/status.rb +0 -1
  29. data/lib/karafka/instrumentation/assignments_tracker.rb +34 -0
  30. data/lib/karafka/instrumentation/callbacks/consumer_groups/decorator.rb +19 -0
  31. data/lib/karafka/instrumentation/callbacks/consumer_groups/error.rb +0 -1
  32. data/lib/karafka/instrumentation/callbacks/consumer_groups/statistics.rb +3 -2
  33. data/lib/karafka/instrumentation/critical_errors_listener.rb +85 -0
  34. data/lib/karafka/instrumentation/logger_listener.rb +2 -0
  35. data/lib/karafka/instrumentation/monitor.rb +2 -3
  36. data/lib/karafka/instrumentation/vendors/appsignal/errors_listener.rb +0 -1
  37. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +0 -1
  38. data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +4 -3
  39. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +0 -2
  40. data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +181 -18
  41. data/lib/karafka/pro/admin/recovery/errors.rb +0 -1
  42. data/lib/karafka/pro/admin/recovery.rb +6 -4
  43. data/lib/karafka/pro/base_consumer.rb +5 -5
  44. data/lib/karafka/pro/cleaner/messages/metadata.rb +0 -1
  45. data/lib/karafka/pro/cli/parallel_segments/base.rb +1 -2
  46. data/lib/karafka/pro/connection/manager.rb +7 -4
  47. data/lib/karafka/pro/encryption/messages/middleware.rb +5 -0
  48. data/lib/karafka/pro/encryption/messages/parser.rb +4 -0
  49. data/lib/karafka/pro/instrumentation/callbacks/consumer_groups/decorator.rb +63 -0
  50. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/compensator.rb +120 -0
  51. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/fetcher.rb +88 -0
  52. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/refresher.rb +185 -0
  53. data/lib/karafka/pro/instrumentation/consumer_groups/lag_compensation/registry.rb +102 -0
  54. data/lib/karafka/pro/instrumentation/performance_tracker.rb +40 -6
  55. data/lib/karafka/pro/iterator/tpl_builder.rb +27 -7
  56. data/lib/karafka/pro/iterator.rb +22 -7
  57. data/lib/karafka/pro/loader.rb +12 -0
  58. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/consumer.rb +0 -3
  59. data/lib/karafka/pro/processing/consumer_groups/adaptive_iterator/tracker.rb +2 -4
  60. data/lib/karafka/pro/processing/consumer_groups/collapser.rb +6 -9
  61. data/lib/karafka/pro/processing/consumer_groups/coordinator.rb +1 -4
  62. data/lib/karafka/pro/processing/consumer_groups/coordinators/errors_tracker.rb +0 -3
  63. data/lib/karafka/pro/processing/consumer_groups/coordinators/filters_applier.rb +21 -10
  64. data/lib/karafka/pro/processing/consumer_groups/coordinators/virtual_offset_manager.rb +4 -4
  65. data/lib/karafka/pro/processing/consumer_groups/expansions_selector.rb +0 -3
  66. data/lib/karafka/pro/processing/consumer_groups/filters/actions.rb +84 -0
  67. data/lib/karafka/pro/processing/consumer_groups/filters/base.rb +5 -6
  68. data/lib/karafka/pro/processing/consumer_groups/filters/delayer.rb +2 -5
  69. data/lib/karafka/pro/processing/consumer_groups/filters/expirer.rb +1 -4
  70. data/lib/karafka/pro/processing/consumer_groups/filters/inline_insights_delayer.rb +1 -4
  71. data/lib/karafka/pro/processing/consumer_groups/filters/throttler.rb +2 -5
  72. data/lib/karafka/pro/processing/consumer_groups/filters/virtual_limiter.rb +0 -3
  73. data/lib/karafka/pro/processing/consumer_groups/jobs/consume_non_blocking.rb +2 -3
  74. data/lib/karafka/pro/processing/consumer_groups/jobs/eofed_non_blocking.rb +0 -2
  75. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic.rb +2 -3
  76. data/lib/karafka/pro/processing/consumer_groups/jobs/periodic_non_blocking.rb +0 -2
  77. data/lib/karafka/pro/processing/consumer_groups/jobs/revoked_non_blocking.rb +0 -3
  78. data/lib/karafka/pro/processing/consumer_groups/jobs_builder.rb +5 -4
  79. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/consumer.rb +3 -7
  80. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/fetcher.rb +8 -10
  81. data/lib/karafka/pro/processing/consumer_groups/offset_metadata/listener.rb +0 -3
  82. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/base.rb +3 -5
  83. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/default.rb +0 -3
  84. data/lib/karafka/pro/processing/consumer_groups/parallel_segments/filters/mom.rb +0 -3
  85. data/lib/karafka/pro/processing/consumer_groups/partitioner.rb +2 -5
  86. data/lib/karafka/pro/processing/consumer_groups/periodic_job/consumer.rb +2 -5
  87. data/lib/karafka/pro/processing/consumer_groups/piping/consumer.rb +2 -5
  88. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom.rb +10 -9
  89. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_lrj_mom_vp.rb +11 -10
  90. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom.rb +0 -3
  91. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_ftr_mom_vp.rb +0 -3
  92. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom.rb +8 -7
  93. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_lrj_mom_vp.rb +9 -8
  94. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom.rb +5 -8
  95. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/dlq_mom_vp.rb +3 -6
  96. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom.rb +4 -7
  97. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_lrj_mom_vp.rb +6 -9
  98. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom.rb +3 -7
  99. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/ftr_mom_vp.rb +4 -8
  100. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom.rb +3 -6
  101. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/lrj_mom_vp.rb +4 -7
  102. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom.rb +2 -5
  103. data/lib/karafka/pro/processing/consumer_groups/strategies/aj/mom_vp.rb +3 -6
  104. data/lib/karafka/pro/processing/consumer_groups/strategies/base.rb +0 -3
  105. data/lib/karafka/pro/processing/consumer_groups/strategies/default.rb +56 -33
  106. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/default.rb +27 -14
  107. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr.rb +0 -3
  108. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj.rb +4 -7
  109. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom.rb +5 -8
  110. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_mom_vp.rb +5 -8
  111. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_lrj_vp.rb +3 -7
  112. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom.rb +0 -3
  113. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_mom_vp.rb +0 -3
  114. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/ftr_vp.rb +0 -3
  115. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj.rb +2 -5
  116. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom.rb +0 -3
  117. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_mom_vp.rb +0 -3
  118. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/lrj_vp.rb +3 -6
  119. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom.rb +0 -3
  120. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/mom_vp.rb +3 -6
  121. data/lib/karafka/pro/processing/consumer_groups/strategies/dlq/vp.rb +65 -8
  122. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/default.rb +0 -4
  123. data/lib/karafka/pro/processing/consumer_groups/strategies/ftr/vp.rb +2 -5
  124. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/default.rb +0 -3
  125. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr.rb +3 -6
  126. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom.rb +4 -7
  127. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_mom_vp.rb +4 -8
  128. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/ftr_vp.rb +3 -6
  129. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom.rb +2 -5
  130. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/mom_vp.rb +3 -7
  131. data/lib/karafka/pro/processing/consumer_groups/strategies/lrj/vp.rb +2 -5
  132. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/default.rb +0 -3
  133. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr.rb +0 -3
  134. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/ftr_vp.rb +0 -3
  135. data/lib/karafka/pro/processing/consumer_groups/strategies/mom/vp.rb +0 -3
  136. data/lib/karafka/pro/processing/consumer_groups/strategies/vp/default.rb +11 -6
  137. data/lib/karafka/pro/processing/consumer_groups/strategy_selector.rb +0 -3
  138. data/lib/karafka/pro/processing/consumer_groups/subscription_groups_coordinator.rb +0 -3
  139. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/balanced.rb +0 -3
  140. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/base.rb +2 -4
  141. data/lib/karafka/pro/processing/consumer_groups/virtual_partitions/distributors/consistent.rb +0 -3
  142. data/lib/karafka/pro/processing/jobs_queue.rb +4 -1
  143. data/lib/karafka/pro/processing/schedulers/base.rb +4 -2
  144. data/lib/karafka/pro/processing/schedulers/default.rb +2 -2
  145. data/lib/karafka/pro/recurring_tasks/consumer.rb +9 -2
  146. data/lib/karafka/pro/recurring_tasks/contracts/config.rb +0 -1
  147. data/lib/karafka/pro/recurring_tasks/executor.rb +25 -13
  148. data/lib/karafka/pro/routing/features/consumer_groups/direct_assignments/subscription_group.rb +0 -2
  149. data/lib/karafka/pro/routing/features/consumer_groups/long_running_job.rb +0 -2
  150. data/lib/karafka/pro/routing/features/consumer_groups/multiplexing/proxy.rb +2 -2
  151. data/lib/karafka/pro/routing/features/consumer_groups/non_blocking_job.rb +0 -2
  152. data/lib/karafka/pro/routing/features/consumer_groups/offset_metadata/topic.rb +0 -6
  153. data/lib/karafka/pro/routing/features/consumer_groups/parallel_segments/consumer_group.rb +5 -4
  154. data/lib/karafka/pro/routing/features/consumer_groups/patterns/config.rb +0 -6
  155. data/lib/karafka/pro/routing/features/consumer_groups/patterns/consumer_group.rb +2 -1
  156. data/lib/karafka/pro/routing/features/consumer_groups/patterns/contracts/pattern.rb +0 -1
  157. data/lib/karafka/pro/routing/features/consumer_groups/patterns/detector.rb +2 -1
  158. data/lib/karafka/pro/routing/features/consumer_groups/patterns/pattern.rb +2 -1
  159. data/lib/karafka/pro/routing/features/consumer_groups/patterns/topics.rb +8 -8
  160. data/lib/karafka/pro/routing/features/consumer_groups/periodic_job/topic.rb +5 -5
  161. data/lib/karafka/pro/routing/features/consumer_groups/recurring_tasks/builder.rb +33 -13
  162. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/builder.rb +52 -28
  163. data/lib/karafka/pro/routing/features/consumer_groups/scheduled_messages/topic.rb +2 -1
  164. data/lib/karafka/pro/routing/features/consumer_groups/virtual_partitions/topic.rb +6 -5
  165. data/lib/karafka/pro/scheduled_messages/consumer.rb +7 -1
  166. data/lib/karafka/pro/scheduled_messages/schema_validator.rb +6 -1
  167. data/lib/karafka/pro/swarm/liveness_listener.rb +118 -13
  168. data/lib/karafka/pro.rb +0 -6
  169. data/lib/karafka/processing/consumer_groups/coordinator.rb +4 -5
  170. data/lib/karafka/processing/consumer_groups/coordinators_buffer.rb +6 -2
  171. data/lib/karafka/processing/consumer_groups/executor.rb +4 -4
  172. data/lib/karafka/processing/consumer_groups/executors_buffer.rb +2 -4
  173. data/lib/karafka/processing/consumer_groups/expansions_selector.rb +0 -2
  174. data/lib/karafka/processing/consumer_groups/inline_insights/consumer.rb +0 -2
  175. data/lib/karafka/processing/consumer_groups/inline_insights/listener.rb +0 -2
  176. data/lib/karafka/processing/consumer_groups/inline_insights/tracker.rb +14 -16
  177. data/lib/karafka/processing/consumer_groups/jobs/consume.rb +2 -5
  178. data/lib/karafka/processing/consumer_groups/jobs/eofed.rb +2 -3
  179. data/lib/karafka/processing/consumer_groups/jobs/idle.rb +2 -2
  180. data/lib/karafka/processing/consumer_groups/jobs/revoked.rb +2 -4
  181. data/lib/karafka/processing/consumer_groups/jobs/shutdown.rb +2 -2
  182. data/lib/karafka/processing/consumer_groups/partitioner.rb +3 -6
  183. data/lib/karafka/processing/consumer_groups/strategies/aj_dlq_mom.rb +5 -2
  184. data/lib/karafka/processing/consumer_groups/strategies/aj_mom.rb +2 -4
  185. data/lib/karafka/processing/consumer_groups/strategies/base.rb +3 -5
  186. data/lib/karafka/processing/consumer_groups/strategies/default.rb +43 -13
  187. data/lib/karafka/processing/consumer_groups/strategies/dlq.rb +5 -2
  188. data/lib/karafka/processing/consumer_groups/strategies/dlq_mom.rb +5 -2
  189. data/lib/karafka/processing/consumer_groups/strategies/mom.rb +2 -3
  190. data/lib/karafka/processing/consumer_groups/strategy_selector.rb +0 -2
  191. data/lib/karafka/processing/coordinator.rb +0 -2
  192. data/lib/karafka/processing/coordinators_buffer.rb +0 -2
  193. data/lib/karafka/processing/partitioner.rb +0 -2
  194. data/lib/karafka/processing/strategy_selector.rb +0 -2
  195. data/lib/karafka/processing/worker.rb +14 -6
  196. data/lib/karafka/processing/workers_pool.rb +21 -4
  197. data/lib/karafka/railtie.rb +0 -1
  198. data/lib/karafka/routing/contracts/routing.rb +2 -2
  199. data/lib/karafka/routing/features/consumer_groups/active_job/topic.rb +6 -5
  200. data/lib/karafka/routing/features/consumer_groups/manual_offset_management/topic.rb +2 -2
  201. data/lib/karafka/routing/features/deserializers/topic.rb +0 -1
  202. data/lib/karafka/routing/subscription_group.rb +1 -1
  203. data/lib/karafka/routing/topic.rb +4 -4
  204. data/lib/karafka/routing/topics.rb +21 -1
  205. data/lib/karafka/server.rb +9 -0
  206. data/lib/karafka/setup/config.rb +54 -10
  207. data/lib/karafka/setup/config_proxy.rb +2 -1
  208. data/lib/karafka/setup/contracts/config.rb +14 -0
  209. data/lib/karafka/swarm/node.rb +2 -2
  210. data/lib/karafka/version.rb +1 -2
  211. data/lib/karafka.rb +2 -2
  212. metadata +12 -4
@@ -52,6 +52,39 @@ module Karafka
52
52
  tasks_cfg = App.config.recurring_tasks
53
53
  topics_cfg = tasks_cfg.topics
54
54
 
55
+ # Declarative topic definitions live independently of routing. We declare the
56
+ # broker-side structure here so it is managed by the CLI topics commands without
57
+ # relying on the (to be retired) routing `config(...)` bridge.
58
+ #
59
+ # We guard each declaration with `find_topic` because `Declaratives::Builder#topic`
60
+ # re-applies its block on an already existing declaration (additive semantics),
61
+ # unlike the old bridge which used `||=` and kept the first declaration. Without the
62
+ # guard, our framework defaults would clobber a topic the user may have declared
63
+ # themselves via `App.declaratives.draw`. Skipping when already present preserves
64
+ # first-declaration-wins.
65
+ App.declaratives.draw do
66
+ # Keep older data for a day and compact to the last state available
67
+ unless find_topic(topics_cfg.schedules.name)
68
+ topic(topics_cfg.schedules.name) do
69
+ config(
70
+ "cleanup.policy": "compact,delete",
71
+ "retention.ms": 86_400_000
72
+ )
73
+ end
74
+ end
75
+
76
+ # Keep cron logs of executions for a week and after that remove. Week should be
77
+ # enough and should not produce too much data.
78
+ unless find_topic(topics_cfg.logs.name)
79
+ topic(topics_cfg.logs.name) do
80
+ config(
81
+ "cleanup.policy": "delete",
82
+ "retention.ms": 604_800_000
83
+ )
84
+ end
85
+ end
86
+ end
87
+
55
88
  consumer_group tasks_cfg.group_id do
56
89
  # Registers the primary topic that we use to control schedules execution. This is
57
90
  # the one that we use to trigger recurring tasks.
@@ -87,12 +120,6 @@ module Karafka
87
120
  pause_timeout(60 * 1_000)
88
121
  pause_max_timeout(60 * 1_000)
89
122
 
90
- # Keep older data for a day and compact to the last state available
91
- config(
92
- "cleanup.policy": "compact,delete",
93
- "retention.ms": 86_400_000
94
- )
95
-
96
123
  # This is the core of execution. Since we're producers of states, we need a way
97
124
  # to tick without having new data
98
125
  periodic(
@@ -113,13 +140,6 @@ module Karafka
113
140
  active(false)
114
141
  deserializer tasks_cfg.deserializer
115
142
  target.recurring_tasks(true)
116
-
117
- # Keep cron logs of executions for a week and after that remove. Week should be
118
- # enough and should not produce too much data.
119
- config(
120
- "cleanup.policy": "delete",
121
- "retention.ms": 604_800_000
122
- )
123
143
  end
124
144
 
125
145
  yield(schedules_topic, logs_topic) if block && block.arity.positive?
@@ -38,9 +38,9 @@ module Karafka
38
38
  module Builder
39
39
  # Enabled scheduled messages operations and adds needed topics and other stuff.
40
40
  #
41
- # @param topic_name [String, false] name for scheduled messages topic that is also used
42
- # as a group identifier. Users can have multiple schedule topics flows to prevent key
43
- # collisions, prioritize and do other stuff. `false` if not active.
41
+ # @param topic_name [String, false] name for scheduled messages topic that is also
42
+ # used as a group identifier. Users can have multiple schedule topics flows to
43
+ # prevent key collisions, prioritize and do other stuff. `false` if not active.
44
44
  # @param block [Proc] optional reconfiguration of the topics definitions.
45
45
  # @note Namespace for topics should include the divider as it is not automatically
46
46
  # added.
@@ -54,6 +54,54 @@ module Karafka
54
54
  # should have same partition count.
55
55
  default_partitions = 5
56
56
  msg_cfg = App.config.scheduled_messages
57
+ states_topic_name = "#{topic_name}#{msg_cfg.states_postfix}"
58
+
59
+ # Declarative topic definitions live independently of routing. We declare the
60
+ # broker-side structure here so it is managed by the CLI topics commands without
61
+ # relying on the (to be retired) routing `config(...)` bridge.
62
+ #
63
+ # We guard each declaration with `find_topic` because `Declaratives::Builder#topic`
64
+ # re-applies its block on an already existing declaration (additive semantics),
65
+ # unlike the old bridge which used `||=` and kept the first declaration. Without the
66
+ # guard, our framework defaults would clobber a topic the user may have declared
67
+ # themselves via `App.declaratives.draw`. Skipping when already present preserves
68
+ # first-declaration-wins.
69
+ App.declaratives.draw do
70
+ # This is a setup that should allow messages to be compacted fairly fast. Since
71
+ # each dispatched message should be removed via tombstone, they do not have to
72
+ # be present in the topic for too long.
73
+ unless find_topic(topic_name)
74
+ topic(topic_name) do
75
+ partitions default_partitions
76
+ config(
77
+ # Will ensure, that after tombstone is present, given scheduled message,
78
+ # that has been dispatched is removed by Kafka
79
+ "cleanup.policy": "compact",
80
+ # When 10% or more dispatches are done, compact data
81
+ "min.cleanable.dirty.ratio": 0.1,
82
+ # Frequent segment rotation to support intense compaction
83
+ "segment.ms": 3_600_000,
84
+ "delete.retention.ms": 3_600_000,
85
+ "segment.bytes": 52_428_800
86
+ )
87
+ end
88
+ end
89
+
90
+ # Holds states of scheduler per each of the partitions. Same partition count as
91
+ # the messages topic since they tick independently per partition.
92
+ unless find_topic(states_topic_name)
93
+ topic(states_topic_name) do
94
+ partitions default_partitions
95
+ config(
96
+ "cleanup.policy": "compact",
97
+ "min.cleanable.dirty.ratio": 0.1,
98
+ "segment.ms": 3_600_000,
99
+ "delete.retention.ms": 3_600_000,
100
+ "segment.bytes": 52_428_800
101
+ )
102
+ end
103
+ end
104
+ end
57
105
 
58
106
  consumer_group msg_cfg.group_id do
59
107
  # Registers the primary topic that we use to control schedules execution. This is
@@ -93,22 +141,6 @@ module Karafka
93
141
 
94
142
  max_wait_time(1_000)
95
143
 
96
- # This is a setup that should allow messages to be compacted fairly fast. Since
97
- # each dispatched message should be removed via tombstone, they do not have to
98
- # be present in the topic for too long.
99
- config(
100
- partitions: default_partitions,
101
- # Will ensure, that after tombstone is present, given scheduled message, that
102
- # has been dispatched is removed by Kafka
103
- "cleanup.policy": "compact",
104
- # When 10% or more dispatches are done, compact data
105
- "min.cleanable.dirty.ratio": 0.1,
106
- # Frequent segment rotation to support intense compaction
107
- "segment.ms": 3_600_000,
108
- "delete.retention.ms": 3_600_000,
109
- "segment.bytes": 52_428_800
110
- )
111
-
112
144
  # This is the core of execution. Since we dispatch data in time intervals, we
113
145
  # need to be able to do this even when no new data is coming
114
146
  periodic(
@@ -126,17 +158,9 @@ module Karafka
126
158
  # Holds states of scheduler per each of the partitions since they tick
127
159
  # independently. We only hold future statistics not to have to deal with
128
160
  # any type of state restoration
129
- states_topic = topic("#{topic_name}#{msg_cfg.states_postfix}") do
161
+ states_topic = topic(states_topic_name) do
130
162
  active(false)
131
163
  target.scheduled_messages(true)
132
- config(
133
- partitions: default_partitions,
134
- "cleanup.policy": "compact",
135
- "min.cleanable.dirty.ratio": 0.1,
136
- "segment.ms": 3_600_000,
137
- "delete.retention.ms": 3_600_000,
138
- "segment.bytes": 52_428_800
139
- )
140
164
  deserializers(
141
165
  payload: msg_cfg.deserializers.payload
142
166
  )
@@ -46,7 +46,8 @@ module Karafka
46
46
  super
47
47
  end
48
48
 
49
- # @param active [Boolean] should this topic be considered related to scheduled messages
49
+ # @param active [Boolean] should this topic be considered related to scheduled
50
+ # messages
50
51
  def scheduled_messages(active = false)
51
52
  @scheduled_messages ||= Config.new(active: active)
52
53
  end
@@ -45,16 +45,17 @@ module Karafka
45
45
  super
46
46
  end
47
47
 
48
- # @param max_partitions [Integer] max number of virtual partitions that can come out of
49
- # the single distribution flow. When set to more than the Karafka threading, will
48
+ # @param max_partitions [Integer] max number of virtual partitions that can come out
49
+ # of the single distribution flow. When set to more than the Karafka threading, will
50
50
  # create more work than workers. When less, can ensure we have spare resources to
51
51
  # process other things in parallel.
52
52
  # @param partitioner [nil, #call] nil or callable partitioner
53
53
  # @param offset_metadata_strategy [Symbol] how we should match the metadata for the
54
- # offset. `:exact` will match the offset matching metadata and `:current` will select
55
- # the most recently reported metadata
54
+ # offset. `:exact` will match the offset matching metadata and `:current` will
55
+ # select the most recently reported metadata
56
56
  # @param reducer [nil, #call] reducer for VPs key. It allows for using a custom
57
- # reducer to achieve enhanced parallelization when the default reducer is not enough.
57
+ # reducer to achieve enhanced parallelization when the default reducer is not
58
+ # enough.
58
59
  # @param distribution [Symbol] the strategy to use for virtual partitioning. Can be
59
60
  # either `:consistent` or `:balanced`. The `:balanced` strategy ensures balanced
60
61
  # distribution of work across available workers while maintaining message order
@@ -72,7 +72,13 @@ module Karafka
72
72
 
73
73
  @states_reporter.call
74
74
 
75
- recent_timestamp = messages.last.timestamp.to_i
75
+ # Clamp to the wall clock: a future-dated message timestamp (producer clock skew or an
76
+ # explicitly set future timestamp) must not be treated as proof of catch-up. Otherwise a
77
+ # single future-dated message read mid-backlog would flip `loaded!` while older tombstones
78
+ # at higher offsets are still unread, dispatching schedules whose cancelling tombstones
79
+ # have not been loaded yet (double dispatch). Mirrors the `[timestamp, now].min` clamp in
80
+ # the batch metadata builder.
81
+ recent_timestamp = [messages.last.timestamp.to_i, Time.now.to_i].min
76
82
  post_started_timestamp = @tracker.started_at + GRACE_PERIOD
77
83
 
78
84
  # If we started getting messages that are beyond the current time, it means we have
@@ -43,7 +43,12 @@ module Karafka
43
43
  def call(message)
44
44
  message_version = message.headers["schedule_schema_version"]
45
45
 
46
- return if message_version <= ScheduledMessages::SCHEMA_VERSION
46
+ # Versions are semver, so they need to be compared segment-wise and not as strings
47
+ # ("1.2.0" is older than "1.10.0" but lexicographically greater)
48
+ message_gem_version = Gem::Version.new(message_version)
49
+ current_gem_version = Gem::Version.new(ScheduledMessages::SCHEMA_VERSION)
50
+
51
+ return if message_gem_version <= current_gem_version
47
52
 
48
53
  raise Errors::IncompatibleSchemaError, message_version
49
54
  end
@@ -47,28 +47,50 @@ module Karafka
47
47
  # - 1 - polling ttl exceeded
48
48
  # - 2 - consuming ttl exceeded
49
49
  # - 3 - memory limit exceeded
50
+ # - 4 - stability ttl exceeded (stuck in non-steady librdkafka join state)
50
51
  #
51
52
  # @note This listener should not break anything if subscribed in the supervisor prior to
52
53
  # forking as it relies on server events for operations.
53
54
  class LivenessListener < Karafka::Swarm::LivenessListener
55
+ # Default time in ms after which we consider consumption hanging (5 minutes)
56
+ DEFAULT_CONSUMING_TTL = 5 * 60 * 1_000
57
+ # Default max time in ms between polls before the node is considered dead (5 minutes)
58
+ DEFAULT_POLLING_TTL = 5 * 60 * 1_000
59
+ # Multiplier applied to max.poll.interval.ms when deriving the default stability_ttl.
60
+ STABILITY_TTL_MAX_POLL_MULTIPLIER = 2
61
+
62
+ private_constant(
63
+ :DEFAULT_CONSUMING_TTL,
64
+ :DEFAULT_POLLING_TTL,
65
+ :STABILITY_TTL_MAX_POLL_MULTIPLIER
66
+ )
67
+
54
68
  # @param memory_limit [Integer] max memory in MB for this process to be considered healthy
55
- # @param consuming_ttl [Integer] time in ms after which we consider consumption hanging.
56
- # It allows us to define max consumption time after which supervisor should consider
57
- # given process as hanging
58
- # @param polling_ttl [Integer] max time in ms for polling. If polling (any) does not
59
- # happen that often, process should be considered dead.
60
- # @note The default TTL matches the default `max.poll.interval.ms`
69
+ # @param consuming_ttl [Integer] see Kubernetes::LivenessListener for full documentation.
70
+ # @param polling_ttl [Integer] see Kubernetes::LivenessListener for full documentation.
71
+ # @param stability_ttl [Integer, nil] see Kubernetes::LivenessListener for full
72
+ # documentation, including the derivation rules (max `max.poll.interval.ms` across
73
+ # all active subscription groups, times 2, resolved lazily on first health
74
+ # evaluation). Same semantics apply here; the node is reported unhealthy with
75
+ # status code 4 instead of returning HTTP 500.
61
76
  def initialize(
62
77
  memory_limit: Float::INFINITY,
63
- consuming_ttl: 5 * 60 * 1_000,
64
- polling_ttl: 5 * 60 * 1_000
78
+ consuming_ttl: DEFAULT_CONSUMING_TTL,
79
+ polling_ttl: DEFAULT_POLLING_TTL,
80
+ stability_ttl: nil
65
81
  )
66
82
  @polling_ttl = polling_ttl
67
83
  @consuming_ttl = consuming_ttl
84
+ # When nil, resolved lazily via #stability_ttl on first health evaluation because
85
+ # the default derives from the routing subscription groups, which may not be drawn
86
+ # yet when the listener is constructed in karafka.rb
87
+ @stability_ttl = stability_ttl
68
88
  # We cast it just in case someone would provide '10MB' or something similar
69
89
  @memory_limit = memory_limit.is_a?(String) ? memory_limit.to_i : memory_limit
70
90
  @pollings = {}
71
91
  @consumptions = {}
92
+ @join_states = {}
93
+ @instabilities = {}
72
94
 
73
95
  super()
74
96
  end
@@ -117,6 +139,27 @@ module Karafka
117
139
  RUBY
118
140
  end
119
141
 
142
+ # @see Karafka::Instrumentation::Vendors::Kubernetes::LivenessListener#on_statistics_emitted
143
+ # @param event [Karafka::Core::Monitoring::Event]
144
+ def on_statistics_emitted(event)
145
+ cgrp = event[:statistics]&.dig("cgrp")
146
+ return unless cgrp
147
+
148
+ sg_id = event[:subscription_group_id]
149
+ join_state = cgrp["join_state"]
150
+ return unless join_state
151
+
152
+ synchronize do
153
+ if join_state == "steady" || join_state == "init" || join_state == "wait-metadata"
154
+ @instabilities.delete(sg_id)
155
+ @join_states.delete(sg_id)
156
+ elsif @join_states[sg_id] != join_state
157
+ @join_states[sg_id] = join_state
158
+ @instabilities[sg_id] = monotonic_now
159
+ end
160
+ end
161
+ end
162
+
120
163
  # @param _event [Karafka::Core::Monitoring::Event]
121
164
  def on_error_occurred(_event)
122
165
  clear_consumption_tick
@@ -143,6 +186,13 @@ module Karafka
143
186
  clear_polling_tick
144
187
  end
145
188
 
189
+ # @see Karafka::Instrumentation::Vendors::Kubernetes::LivenessListener
190
+ # #on_connection_listener_after_fetch_loop
191
+ # @param event [Karafka::Core::Monitoring::Event]
192
+ def on_connection_listener_after_fetch_loop(event)
193
+ clear_instability_tracking(event[:subscription_group])
194
+ end
195
+
146
196
  private
147
197
 
148
198
  # Reports the current status to the supervisor periodically
@@ -158,10 +208,21 @@ module Karafka
158
208
  end
159
209
  end
160
210
 
161
- # @return [Integer] object id of the current fiber
162
- # @note We use fiber object id instead of thread object id to ensure fiber-safety.
163
- # Multiple fibers can run on the same thread, and using thread id would cause them
164
- # to overwrite each other's timestamps.
211
+ # @see Karafka::Instrumentation::Vendors::Kubernetes::LivenessListener
212
+ # #clear_instability_tracking
213
+ # @param subscription_group [Karafka::Routing::SubscriptionGroup, nil]
214
+ def clear_instability_tracking(subscription_group)
215
+ return unless subscription_group
216
+
217
+ sg_id = subscription_group.id
218
+
219
+ synchronize do
220
+ @instabilities.delete(sg_id)
221
+ @join_states.delete(sg_id)
222
+ end
223
+ end
224
+
225
+ # @see Karafka::Instrumentation::Vendors::Kubernetes::LivenessListener#fiber_id
165
226
  def fiber_id
166
227
  Fiber.current.object_id
167
228
  end
@@ -195,17 +256,61 @@ module Karafka
195
256
  end
196
257
 
197
258
  # Did we exceed any of the ttls
198
- # @return [String] 204 string if ok, 500 otherwise
259
+ # @return [Integer] 0 if healthy, positive error code otherwise:
260
+ # 1 - polling TTL exceeded
261
+ # 2 - consuming TTL exceeded
262
+ # 3 - memory limit exceeded
263
+ # 4 - stability TTL exceeded (stuck in non-steady join state)
264
+ # @note Reads `@pollings`, `@consumptions` and `@instabilities` without acquiring the
265
+ # mutex. This is intentional and consistent across all three: `status` is called from
266
+ # inside `periodically`, which already holds `@mutex` for scheduling, so re-entering
267
+ # `synchronize` here would deadlock. Concurrent writes from `mark_*` / `clear_*` /
268
+ # `on_statistics_emitted` are safe to observe partially on MRI (GVL atomises Hash ops).
269
+ # This is the asymmetry vs `Kubernetes::LivenessListener`, which can lock its reads
270
+ # because it has no equivalent periodic-scheduling lock. Do not "fix" this without
271
+ # resolving the periodic-scheduling lock first - JRuby is not a supported runtime.
199
272
  def status
200
273
  time = monotonic_now
201
274
 
202
275
  return 1 if @pollings.values.any? { |tick| (time - tick) > @polling_ttl }
203
276
  return 2 if @consumptions.values.any? { |tick| (time - tick) > @consuming_ttl }
204
277
  return 3 if rss_mb > @memory_limit
278
+ return 4 if @instabilities.values.any? { |start| (time - start) > stability_ttl }
205
279
 
206
280
  0
207
281
  end
208
282
 
283
+ # @return [Integer] effective stability ttl in ms. Resolved lazily (instead of in
284
+ # `#initialize`) because the default derives from the routing subscription groups,
285
+ # which may not be drawn yet when the listener is constructed in karafka.rb. By the
286
+ # time status is evaluated, routing is final.
287
+ def stability_ttl
288
+ @stability_ttl ||= default_stability_ttl
289
+ end
290
+
291
+ # @return [Integer] default stability_ttl derived from the configured
292
+ # max.poll.interval.ms, multiplied by 2 for headroom above the slowest legitimate
293
+ # rebalance phase. Uses the maximum value across all active subscription groups
294
+ # (their kafka configs already have librdkafka defaults injected), so per
295
+ # subscription group overrides set via the routing DSL are respected. Falls back to
296
+ # the root kafka config when no subscription groups are available.
297
+ def default_stability_ttl
298
+ max_poll_interval = Karafka::App
299
+ .subscription_groups
300
+ .values
301
+ .flatten
302
+ .map { |sg| sg.kafka.fetch(:"max.poll.interval.ms") }
303
+ .max
304
+
305
+ max_poll_interval ||= begin
306
+ kafka_config = Karafka::App.config.kafka.dup
307
+ Karafka::Setup::DefaultsInjector.consumer(kafka_config)
308
+ kafka_config.fetch(:"max.poll.interval.ms")
309
+ end
310
+
311
+ max_poll_interval * STABILITY_TTL_MAX_POLL_MULTIPLIER
312
+ end
313
+
209
314
  # @return [Integer] RSS in MB for the current process
210
315
  def rss_mb
211
316
  RUBY_PLATFORM.include?("linux") ? rss_mb_linux : rss_mb_macos
data/lib/karafka/pro.rb CHANGED
@@ -1,11 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This Karafka component is a Pro component.
4
- # All of the commercial components are present in the lib/karafka/pro directory of this repository
5
- # and their usage requires commercial license agreement.
6
- #
7
- # Karafka has also commercial-friendly license, commercial support and commercial components.
8
- #
9
3
  module Karafka
10
4
  # Namespace for pro components, licensed under the commercial license agreement.
11
5
  module Pro
@@ -2,16 +2,14 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  # Basic coordinator that allows us to provide coordination objects into consumers.
9
7
  #
10
8
  # This is a wrapping layer to simplify management of work to be handled around consumption.
11
9
  #
12
10
  # @note This coordinator needs to be thread safe. Some operations are performed only in the
13
- # listener thread, but we go with thread-safe by default for all not to worry about potential
14
- # future mistakes.
11
+ # listener thread, but we go with thread-safe by default for all not to worry about
12
+ # potential future mistakes.
15
13
  class Coordinator
16
14
  extend Forwardable
17
15
  include Core::Helpers::Time
@@ -29,7 +27,8 @@ module Karafka
29
27
 
30
28
  # @param topic [Karafka::Routing::Topic]
31
29
  # @param partition [Integer]
32
- # @param pause_tracker [Karafka::TimeTrackers::Pause] pause tracker for given topic partition
30
+ # @param pause_tracker [Karafka::TimeTrackers::Pause] pause tracker for given topic
31
+ # partition
33
32
  def initialize(topic, partition, pause_tracker)
34
33
  @topic = topic
35
34
  @partition = partition
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  # Coordinators builder used to build coordinators per topic partition
9
7
  #
@@ -50,6 +48,12 @@ module Karafka
50
48
  def revoke(topic_name, partition)
51
49
  return unless @coordinators[topic_name].key?(partition)
52
50
 
51
+ # Reset the partition's pause tracker attempt count. The tracker lives in the pauses
52
+ # manager keyed by topic-partition and would otherwise be reused as-is if we reclaim this
53
+ # partition, carrying a stale retry attempt count across the rebalance (which, with DLQ,
54
+ # would send the next failure straight to the dead letter queue, skipping the retries)
55
+ @pauses_manager.revoke(@topics.find(topic_name), partition)
56
+
53
57
  # The fact that we delete here does not change the fact that the executor still holds the
54
58
  # reference to this coordinator. We delete it here, as we will no longer process any
55
59
  # new stuff with it and we may need a new coordinator if we regain this partition, but the
@@ -7,8 +7,8 @@ module Karafka
7
7
  # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
8
8
  module ConsumerGroups
9
9
  # Executors:
10
- # - run consumers code (for `#call`) or run given preparation / teardown operations when needed
11
- # from separate threads.
10
+ # - run consumers code (for `#call`) or run given preparation / teardown operations when
11
+ # needed from separate threads.
12
12
  # - they re-create consumer instances in case of partitions that were revoked and assigned
13
13
  # back.
14
14
  #
@@ -54,8 +54,8 @@ module Karafka
54
54
  @coordinator = coordinator
55
55
  end
56
56
 
57
- # Allows us to prepare the consumer in the listener thread prior to the job being send to
58
- # be scheduled. It also allows to run some code that is time sensitive and cannot wait in the
57
+ # Allows us to prepare the consumer in the listener thread prior to the job being send to be
58
+ # scheduled. It also allows to run some code that is time sensitive and cannot wait in the
59
59
  # queue as it could cause starvation.
60
60
  #
61
61
  # @param messages [Array<Karafka::Messages::Message>]
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  # Buffer for executors of a given subscription group. It wraps around the concept of building
9
7
  # and caching them, so we can re-use them instead of creating new each time.
@@ -63,8 +61,8 @@ module Karafka
63
61
  #
64
62
  # @param topic [String] topic name
65
63
  # @param partition [Integer] partition number
66
- # @return [Array<Executor, Pro::Processing::ConsumerGroups::Executor>] executors in use for this
67
- # topic + partition
64
+ # @return [Array<Executor, Pro::Processing::ConsumerGroups::Executor>] executors in use for
65
+ # this topic + partition
68
66
  def find_all(topic, partition)
69
67
  @buffer[topic][partition].values
70
68
  end
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  # Selector of appropriate topic setup based features enhancements.
9
7
  #
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  # Namespace of the Inline Insights feature "non routing" related components
9
7
  #
@@ -2,8 +2,6 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  module InlineInsights
9
7
  # Listener that adds statistics to our inline tracker
@@ -2,31 +2,29 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
6
  module InlineInsights
9
7
  # Object used to track statistics coming from librdkafka in a way that can be accessible by
10
8
  # the consumers
11
9
  #
12
- # We use a single tracker because we do not need state management here as our consumer groups
13
- # clients identified by statistics name value are unique. On top of that, having a per
14
- # process one that is a singleton allows us to use tracker easily also from other places like
15
- # filtering API etc.
10
+ # We use a single tracker because we do not need state management here as our consumer
11
+ # groups clients identified by statistics name value are unique. On top of that, having a
12
+ # per process one that is a singleton allows us to use tracker easily also from other places
13
+ # like filtering API etc.
16
14
  #
17
15
  # @note We include cache of 5 minutes for revoked partitions to compensate for cases where
18
- # when using LRJ a lost partition data would not be present anymore, however we would still
19
- # be in the processing phase. Since those metrics are published with each `poll`, regular
20
- # processing is not a subject of this issue. For LRJ we keep the reference. The only case
21
- # where this could be switched midway is when LRJ is running for an extended period of time
22
- # after the involuntary revocation. Having a time based cache instead of tracking
23
- # simplifies the design as we do not have to deal with state tracking, especially since
24
- # we would have to track also operations running in a revoked state.
16
+ # when using LRJ a lost partition data would not be present anymore, however we would
17
+ # still be in the processing phase. Since those metrics are published with each `poll`,
18
+ # regular processing is not a subject of this issue. For LRJ we keep the reference. The
19
+ # only case where this could be switched midway is when LRJ is running for an extended
20
+ # period of time after the involuntary revocation. Having a time based cache instead of
21
+ # tracking simplifies the design as we do not have to deal with state tracking, especially
22
+ # since we would have to track also operations running in a revoked state.
25
23
  #
26
24
  # @note This tracker keeps in memory data about all topics and partitions that it encounters
27
- # because in case of routing patterns, we may start getting statistics prior to registering
28
- # given topic via dynamic routing expansions. In such case we would not have insights
29
- # where they were actually available for us to use.
25
+ # because in case of routing patterns, we may start getting statistics prior to
26
+ # registering given topic via dynamic routing expansions. In such case we would not have
27
+ # insights where they were actually available for us to use.
30
28
  #
31
29
  # @note Memory usage is negligible as long as we can evict expired data. Single metrics set
32
30
  # for a single partition contains around 4KB of data. This means, that in case of an
@@ -2,10 +2,7 @@
2
2
 
3
3
  module Karafka
4
4
  module Processing
5
- # Consumer-group-specific processing components (driven by rebalance callbacks and partition
6
- # ticks). Parallel `ShareGroups` will live next to this namespace once KIP-932 lands.
7
5
  module ConsumerGroups
8
- # Consumer-group-specific job types
9
6
  module Jobs
10
7
  # The main job type. It runs the executor that triggers given topic partition messages
11
8
  # processing in an underlying consumer instance.
@@ -15,8 +12,8 @@ module Karafka
15
12
 
16
13
  self.action = :consume
17
14
 
18
- # @param executor [Karafka::Processing::ConsumerGroups::Executor] executor that is suppose to run a given
19
- # job
15
+ # @param executor [Karafka::Processing::ConsumerGroups::Executor] executor that is suppose
16
+ # to run a given job
20
17
  # @param messages [Karafka::Messages::Messages] karafka messages batch
21
18
  # @return [Consume]
22
19
  def initialize(executor, messages)