karafka 2.2.13 → 2.3.0.alpha1

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 (125) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/workflows/ci.yml +38 -12
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +161 -125
  6. data/Gemfile.lock +12 -12
  7. data/README.md +0 -2
  8. data/SECURITY.md +23 -0
  9. data/config/locales/errors.yml +7 -1
  10. data/config/locales/pro_errors.yml +22 -0
  11. data/docker-compose.yml +3 -1
  12. data/karafka.gemspec +2 -2
  13. data/lib/karafka/admin/acl.rb +287 -0
  14. data/lib/karafka/admin.rb +118 -16
  15. data/lib/karafka/app.rb +12 -3
  16. data/lib/karafka/base_consumer.rb +32 -31
  17. data/lib/karafka/cli/base.rb +1 -1
  18. data/lib/karafka/connection/client.rb +94 -84
  19. data/lib/karafka/connection/conductor.rb +28 -0
  20. data/lib/karafka/connection/listener.rb +165 -46
  21. data/lib/karafka/connection/listeners_batch.rb +5 -11
  22. data/lib/karafka/connection/manager.rb +72 -0
  23. data/lib/karafka/connection/messages_buffer.rb +12 -0
  24. data/lib/karafka/connection/proxy.rb +17 -0
  25. data/lib/karafka/connection/status.rb +75 -0
  26. data/lib/karafka/contracts/config.rb +14 -10
  27. data/lib/karafka/contracts/consumer_group.rb +9 -1
  28. data/lib/karafka/contracts/topic.rb +3 -1
  29. data/lib/karafka/errors.rb +13 -0
  30. data/lib/karafka/instrumentation/assignments_tracker.rb +96 -0
  31. data/lib/karafka/instrumentation/callbacks/rebalance.rb +10 -7
  32. data/lib/karafka/instrumentation/logger_listener.rb +3 -9
  33. data/lib/karafka/instrumentation/notifications.rb +19 -9
  34. data/lib/karafka/instrumentation/vendors/appsignal/metrics_listener.rb +31 -28
  35. data/lib/karafka/instrumentation/vendors/datadog/logger_listener.rb +22 -3
  36. data/lib/karafka/instrumentation/vendors/datadog/metrics_listener.rb +15 -12
  37. data/lib/karafka/instrumentation/vendors/kubernetes/liveness_listener.rb +39 -36
  38. data/lib/karafka/pro/base_consumer.rb +47 -0
  39. data/lib/karafka/pro/connection/manager.rb +300 -0
  40. data/lib/karafka/pro/connection/multiplexing/listener.rb +40 -0
  41. data/lib/karafka/pro/instrumentation/performance_tracker.rb +85 -0
  42. data/lib/karafka/pro/iterator/tpl_builder.rb +1 -1
  43. data/lib/karafka/pro/iterator.rb +1 -6
  44. data/lib/karafka/pro/loader.rb +16 -2
  45. data/lib/karafka/pro/processing/coordinator.rb +2 -1
  46. data/lib/karafka/pro/processing/executor.rb +37 -0
  47. data/lib/karafka/pro/processing/expansions_selector.rb +32 -0
  48. data/lib/karafka/pro/processing/jobs/periodic.rb +41 -0
  49. data/lib/karafka/pro/processing/jobs/periodic_non_blocking.rb +32 -0
  50. data/lib/karafka/pro/processing/jobs_builder.rb +14 -3
  51. data/lib/karafka/pro/processing/offset_metadata/consumer.rb +44 -0
  52. data/lib/karafka/pro/processing/offset_metadata/fetcher.rb +131 -0
  53. data/lib/karafka/pro/processing/offset_metadata/listener.rb +46 -0
  54. data/lib/karafka/pro/processing/schedulers/base.rb +143 -0
  55. data/lib/karafka/pro/processing/schedulers/default.rb +107 -0
  56. data/lib/karafka/pro/processing/strategies/aj/lrj_mom_vp.rb +1 -1
  57. data/lib/karafka/pro/processing/strategies/default.rb +136 -3
  58. data/lib/karafka/pro/processing/strategies/dlq/default.rb +35 -0
  59. data/lib/karafka/pro/processing/strategies/lrj/default.rb +1 -1
  60. data/lib/karafka/pro/processing/strategies/lrj/mom.rb +1 -1
  61. data/lib/karafka/pro/processing/strategies/vp/default.rb +60 -26
  62. data/lib/karafka/pro/processing/virtual_offset_manager.rb +41 -11
  63. data/lib/karafka/pro/routing/features/long_running_job/topic.rb +2 -0
  64. data/lib/karafka/pro/routing/features/multiplexing/config.rb +38 -0
  65. data/lib/karafka/pro/routing/features/multiplexing/contracts/topic.rb +114 -0
  66. data/lib/karafka/pro/routing/features/multiplexing/patches/contracts/consumer_group.rb +42 -0
  67. data/lib/karafka/pro/routing/features/multiplexing/proxy.rb +38 -0
  68. data/lib/karafka/pro/routing/features/multiplexing/subscription_group.rb +42 -0
  69. data/lib/karafka/pro/routing/features/multiplexing/subscription_groups_builder.rb +40 -0
  70. data/lib/karafka/pro/routing/features/multiplexing.rb +59 -0
  71. data/lib/karafka/pro/routing/features/non_blocking_job/topic.rb +32 -0
  72. data/lib/karafka/pro/routing/features/non_blocking_job.rb +37 -0
  73. data/lib/karafka/pro/routing/features/offset_metadata/config.rb +33 -0
  74. data/lib/karafka/pro/routing/features/offset_metadata/contracts/topic.rb +42 -0
  75. data/lib/karafka/pro/routing/features/offset_metadata/topic.rb +65 -0
  76. data/lib/karafka/pro/routing/features/offset_metadata.rb +40 -0
  77. data/lib/karafka/pro/routing/features/patterns/contracts/consumer_group.rb +4 -0
  78. data/lib/karafka/pro/routing/features/patterns/detector.rb +18 -10
  79. data/lib/karafka/pro/routing/features/periodic_job/config.rb +37 -0
  80. data/lib/karafka/pro/routing/features/periodic_job/contracts/topic.rb +44 -0
  81. data/lib/karafka/pro/routing/features/periodic_job/topic.rb +94 -0
  82. data/lib/karafka/pro/routing/features/periodic_job.rb +27 -0
  83. data/lib/karafka/pro/routing/features/virtual_partitions/config.rb +1 -0
  84. data/lib/karafka/pro/routing/features/virtual_partitions/contracts/topic.rb +1 -0
  85. data/lib/karafka/pro/routing/features/virtual_partitions/topic.rb +7 -2
  86. data/lib/karafka/process.rb +5 -3
  87. data/lib/karafka/processing/coordinator.rb +5 -1
  88. data/lib/karafka/processing/executor.rb +43 -13
  89. data/lib/karafka/processing/executors_buffer.rb +22 -7
  90. data/lib/karafka/processing/jobs/base.rb +19 -2
  91. data/lib/karafka/processing/jobs/consume.rb +3 -3
  92. data/lib/karafka/processing/jobs/idle.rb +5 -0
  93. data/lib/karafka/processing/jobs/revoked.rb +5 -0
  94. data/lib/karafka/processing/jobs/shutdown.rb +5 -0
  95. data/lib/karafka/processing/jobs_queue.rb +19 -8
  96. data/lib/karafka/processing/schedulers/default.rb +42 -0
  97. data/lib/karafka/processing/strategies/base.rb +13 -4
  98. data/lib/karafka/processing/strategies/default.rb +23 -7
  99. data/lib/karafka/processing/strategies/dlq.rb +36 -0
  100. data/lib/karafka/processing/worker.rb +4 -1
  101. data/lib/karafka/routing/builder.rb +12 -2
  102. data/lib/karafka/routing/consumer_group.rb +5 -5
  103. data/lib/karafka/routing/features/base.rb +44 -8
  104. data/lib/karafka/routing/features/dead_letter_queue/config.rb +6 -1
  105. data/lib/karafka/routing/features/dead_letter_queue/contracts/topic.rb +1 -0
  106. data/lib/karafka/routing/features/dead_letter_queue/topic.rb +9 -2
  107. data/lib/karafka/routing/proxy.rb +4 -3
  108. data/lib/karafka/routing/subscription_group.rb +2 -2
  109. data/lib/karafka/routing/subscription_groups_builder.rb +11 -2
  110. data/lib/karafka/routing/topic.rb +8 -10
  111. data/lib/karafka/routing/topics.rb +1 -1
  112. data/lib/karafka/runner.rb +13 -3
  113. data/lib/karafka/server.rb +5 -9
  114. data/lib/karafka/setup/config.rb +21 -1
  115. data/lib/karafka/status.rb +23 -14
  116. data/lib/karafka/templates/karafka.rb.erb +7 -0
  117. data/lib/karafka/time_trackers/partition_usage.rb +56 -0
  118. data/lib/karafka/version.rb +1 -1
  119. data.tar.gz.sig +0 -0
  120. metadata +47 -13
  121. metadata.gz.sig +0 -0
  122. data/lib/karafka/connection/consumer_group_coordinator.rb +0 -48
  123. data/lib/karafka/pro/performance_tracker.rb +0 -84
  124. data/lib/karafka/pro/processing/scheduler.rb +0 -74
  125. data/lib/karafka/processing/scheduler.rb +0 -38
@@ -63,5 +63,18 @@ module Karafka
63
63
 
64
64
  # Raised when there is an attempt to run an unrecognized CLI command
65
65
  UnrecognizedCommandError = Class.new(BaseError)
66
+
67
+ # Raised when we attempt to perform operation that is only allowed inside of a transaction and
68
+ # there is no transaction around us
69
+ TransactionRequiredError = Class.new(BaseError)
70
+
71
+ # Raised in case user would want to perform nested transactions.
72
+ TransactionAlreadyInitializedError = Class.new(BaseError)
73
+
74
+ # Raised in case a listener that was paused is being resumed
75
+ InvalidListenerResumeError = Class.new(BaseError)
76
+
77
+ # Raised when we want to un-pause listener that was not paused
78
+ InvalidListenerPauseError = Class.new(BaseError)
66
79
  end
67
80
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Karafka
4
+ module Instrumentation
5
+ # Keeps track of active assignments and materializes them by returning the routing topics
6
+ # with appropriate partitions that are assigned at a given moment
7
+ #
8
+ # It is auto-subscribed as part of Karafka itself.
9
+ #
10
+ # It is not heavy from the computational point of view, as it only operates during rebalances.
11
+ #
12
+ # We keep assignments as flat topics structure because we can go from topics to both
13
+ # subscription and consumer groups if needed.
14
+ class AssignmentsTracker
15
+ include Singleton
16
+
17
+ def initialize
18
+ @mutex = Mutex.new
19
+ @assignments = Hash.new { |hash, key| hash[key] = [] }
20
+ end
21
+
22
+ # Returns all the active/current assignments of this given process
23
+ #
24
+ # @return [Hash<Karafka::Routing::Topic, Array<Integer>>]
25
+ #
26
+ # @note Keep in mind, that those assignments can change any time, especially when working
27
+ # with multiple consumer groups or subscription groups.
28
+ #
29
+ # @note We return a copy because we modify internals and we do not want user to tamper with
30
+ # the data accidentally
31
+ def current
32
+ assignments = {}
33
+
34
+ @assignments.each do |topic, partitions|
35
+ assignments[topic] = partitions.dup.freeze
36
+ end
37
+
38
+ assignments.freeze
39
+ end
40
+
41
+ # Clears all the assignments
42
+ def clear
43
+ @mutex.synchronize do
44
+ @assignments.clear
45
+ end
46
+ end
47
+
48
+ # When client is under reset due to critical issues, remove all of its assignments as we will
49
+ # get a new set of assignments
50
+ # @param event [Karafka::Core::Monitoring::Event]
51
+ def on_client_reset(event)
52
+ sg = event[:subscription_group]
53
+
54
+ @mutex.synchronize do
55
+ @assignments.delete_if do |topic, _partitions|
56
+ topic.subscription_group.id == sg.id
57
+ end
58
+ end
59
+ end
60
+
61
+ # Removes partitions from the current assignments hash
62
+ #
63
+ # @param event [Karafka::Core::Monitoring::Event]
64
+ def on_rebalance_partitions_revoked(event)
65
+ sg = event[:subscription_group]
66
+
67
+ @mutex.synchronize do
68
+ event[:tpl].to_h.each do |topic, partitions|
69
+ topic = sg.topics.find(topic)
70
+
71
+ @assignments[topic] -= partitions.map(&:partition)
72
+ @assignments[topic].sort!
73
+ # Remove completely topics for which we do not have any assignments left
74
+ @assignments.delete_if { |_topic, cur_partitions| cur_partitions.empty? }
75
+ end
76
+ end
77
+ end
78
+
79
+ # # Adds partitions to the current assignments hash
80
+ #
81
+ # @param event [Karafka::Core::Monitoring::Event]
82
+ def on_rebalance_partitions_assigned(event)
83
+ sg = event[:subscription_group]
84
+
85
+ @mutex.synchronize do
86
+ event[:tpl].to_h.each do |topic, partitions|
87
+ topic = sg.topics.find(topic)
88
+
89
+ @assignments[topic] += partitions.map(&:partition)
90
+ @assignments[topic].sort!
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -6,11 +6,10 @@ module Karafka
6
6
  # Callback that connects to the librdkafka rebalance callback and converts those events into
7
7
  # our internal events
8
8
  class Rebalance
9
- # @param subscription_group_id [String] id of the current subscription group instance
10
- # @param consumer_group_id [String] id of the current consumer group
11
- def initialize(subscription_group_id, consumer_group_id)
12
- @subscription_group_id = subscription_group_id
13
- @consumer_group_id = consumer_group_id
9
+ # @param subscription_group [Karafka::Routes::SubscriptionGroup] subscription group for
10
+ # which we want to manage rebalances
11
+ def initialize(subscription_group)
12
+ @subscription_group = subscription_group
14
13
  end
15
14
 
16
15
  # Publishes an event that partitions are going to be revoked.
@@ -53,8 +52,12 @@ module Karafka
53
52
  ::Karafka.monitor.instrument(
54
53
  "rebalance.#{name}",
55
54
  caller: self,
56
- subscription_group_id: @subscription_group_id,
57
- consumer_group_id: @consumer_group_id,
55
+ # We keep the id references here for backwards compatibility as some of the monitors
56
+ # may use the id references
57
+ subscription_group_id: @subscription_group.id,
58
+ subscription_group: @subscription_group,
59
+ consumer_group_id: @subscription_group.consumer_group.id,
60
+ consumer_group: @subscription_group.consumer_group,
58
61
  tpl: tpl
59
62
  )
60
63
  end
@@ -241,21 +241,15 @@ module Karafka
241
241
  when 'consumer.revoked.error'
242
242
  error "Consumer on revoked failed due to an error: #{error}"
243
243
  error details
244
- when 'consumer.before_enqueue.error'
245
- error "Consumer before enqueue failed due to an error: #{error}"
246
- error details
247
- when 'consumer.before_consume.error'
248
- error "Consumer before consume failed due to an error: #{error}"
249
- error details
250
- when 'consumer.after_consume.error'
251
- error "Consumer after consume failed due to an error: #{error}"
252
- error details
253
244
  when 'consumer.idle.error'
254
245
  error "Consumer idle failed due to an error: #{error}"
255
246
  error details
256
247
  when 'consumer.shutdown.error'
257
248
  error "Consumer on shutdown failed due to an error: #{error}"
258
249
  error details
250
+ when 'consumer.tick.error'
251
+ error "Consumer tick failed due to an error: #{error}"
252
+ error details
259
253
  when 'worker.process.error'
260
254
  fatal "Worker processing failed due to an error: #{error}"
261
255
  fatal details
@@ -20,6 +20,7 @@ module Karafka
20
20
  active_job.consume
21
21
  active_job.consumed
22
22
 
23
+ app.initializing
23
24
  app.initialized
24
25
  app.running
25
26
  app.quieting
@@ -30,27 +31,31 @@ module Karafka
30
31
 
31
32
  client.pause
32
33
  client.resume
34
+ client.reset
33
35
 
34
36
  connection.listener.before_fetch_loop
35
37
  connection.listener.fetch_loop
36
38
  connection.listener.fetch_loop.received
39
+ connection.listener.after_fetch_loop
37
40
 
38
- connection.client.poll.error
39
- connection.client.unsubscribe.error
40
-
41
- rebalance.partitions_assign
42
- rebalance.partitions_assigned
43
- rebalance.partitions_revoke
44
- rebalance.partitions_revoked
45
-
46
- consumer.before_enqueue
41
+ consumer.before_schedule_consume
47
42
  consumer.consume
48
43
  consumer.consumed
49
44
  consumer.consuming.pause
50
45
  consumer.consuming.retry
46
+
47
+ consumer.before_schedule_idle
51
48
  consumer.idle
49
+
50
+ consumer.before_schedule_revoked
52
51
  consumer.revoke
53
52
  consumer.revoked
53
+
54
+ consumer.before_schedule_tick
55
+ consumer.tick
56
+ consumer.ticked
57
+
58
+ consumer.before_schedule_shutdown
54
59
  consumer.shutting_down
55
60
  consumer.shutdown
56
61
 
@@ -61,6 +66,11 @@ module Karafka
61
66
 
62
67
  process.notice_signal
63
68
 
69
+ rebalance.partitions_assign
70
+ rebalance.partitions_assigned
71
+ rebalance.partitions_revoke
72
+ rebalance.partitions_revoked
73
+
64
74
  statistics.emitted
65
75
 
66
76
  worker.process
@@ -42,6 +42,16 @@ module Karafka
42
42
 
43
43
  configure
44
44
 
45
+ # Types of errors originating from user code in the consumer flow
46
+ USER_CONSUMER_ERROR_TYPES = %w[
47
+ consumer.consume.error
48
+ consumer.revoked.error
49
+ consumer.shutdown.error
50
+ consumer.tick.error
51
+ ].freeze
52
+
53
+ private_constant :USER_CONSUMER_ERROR_TYPES
54
+
45
55
  # Before each consumption process, lets start a transaction associated with it
46
56
  # We also set some basic metadata about the given consumption that can be useful for
47
57
  # debugging
@@ -94,34 +104,27 @@ module Karafka
94
104
  client.register_probe(:karafka, -> { minute_probe })
95
105
  end
96
106
 
97
- # Keeps track of revocation user code execution
98
- #
99
- # @param event [Karafka::Core::Monitoring::Event]
100
- def on_consumer_revoke(event)
101
- consumer = event.payload[:caller]
102
- start_transaction(consumer, 'revoked')
103
- end
104
-
105
- # Finishes the revocation transaction
106
- #
107
- # @param _event [Karafka::Core::Monitoring::Event]
108
- def on_consumer_revoked(_event)
109
- stop_transaction
110
- end
111
-
112
- # Keeps track of revocation user code execution
113
- #
114
- # @param event [Karafka::Core::Monitoring::Event]
115
- def on_consumer_shutting_down(event)
116
- consumer = event.payload[:caller]
117
- start_transaction(consumer, 'shutdown')
118
- end
107
+ [
108
+ %i[revoke revoked revoked],
109
+ %i[shutting_down shutdown shutdown],
110
+ %i[tick ticked tick]
111
+ ].each do |before, after, name|
112
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
113
+ # Keeps track of user code execution
114
+ #
115
+ # @param event [Karafka::Core::Monitoring::Event]
116
+ def on_consumer_#{before}(event)
117
+ consumer = event.payload[:caller]
118
+ start_transaction(consumer, '#{name}')
119
+ end
119
120
 
120
- # Finishes the shutdown transaction
121
- #
122
- # @param _event [Karafka::Core::Monitoring::Event]
123
- def on_consumer_shutdown(_event)
124
- stop_transaction
121
+ # Finishes the transaction
122
+ #
123
+ # @param _event [Karafka::Core::Monitoring::Event]
124
+ def on_consumer_#{after}(_event)
125
+ stop_transaction
126
+ end
127
+ RUBY
125
128
  end
126
129
 
127
130
  # Counts DLQ dispatches
@@ -141,7 +144,7 @@ module Karafka
141
144
  # @param event [Karafka::Core::Monitoring::Event] error event details
142
145
  def on_error_occurred(event)
143
146
  # If this is a user consumption related error, we bump the counters for metrics
144
- if event[:type] == 'consumer.consume.error'
147
+ if USER_CONSUMER_ERROR_TYPES.include?(event[:type])
145
148
  consumer = event.payload[:caller]
146
149
 
147
150
  with_multiple_resolutions(consumer) do |tags|
@@ -55,7 +55,24 @@ module Karafka
55
55
  consumer = job.executor.topic.consumer
56
56
  topic = job.executor.topic.name
57
57
 
58
- current_span.resource = "#{consumer}#consume"
58
+ action = case job_type
59
+ when 'Periodic'
60
+ 'tick'
61
+ when 'PeriodicNonBlocking'
62
+ 'tick'
63
+ when 'Shutdown'
64
+ 'shutdown'
65
+ when 'Revoked'
66
+ 'revoked'
67
+ when 'RevokedNonBlocking'
68
+ 'revoked'
69
+ when 'Idle'
70
+ 'idle'
71
+ else
72
+ 'consume'
73
+ end
74
+
75
+ current_span.resource = "#{consumer}##{action}"
59
76
  info "[#{job.id}] #{job_type} job for #{consumer} on #{topic} started"
60
77
 
61
78
  pop_tags
@@ -94,14 +111,16 @@ module Karafka
94
111
  error "Consumer consuming error: #{error}"
95
112
  when 'consumer.revoked.error'
96
113
  error "Consumer on revoked failed due to an error: #{error}"
97
- when 'consumer.before_enqueue.error'
98
- error "Consumer before enqueue failed due to an error: #{error}"
114
+ when 'consumer.before_schedule.error'
115
+ error "Consumer before schedule failed due to an error: #{error}"
99
116
  when 'consumer.before_consume.error'
100
117
  error "Consumer before consume failed due to an error: #{error}"
101
118
  when 'consumer.after_consume.error'
102
119
  error "Consumer after consume failed due to an error: #{error}"
103
120
  when 'consumer.shutdown.error'
104
121
  error "Consumer on shutdown failed due to an error: #{error}"
122
+ when 'consumer.tick.error'
123
+ error "Consumer tick failed due to an error: #{error}"
105
124
  when 'worker.process.error'
106
125
  fatal "Worker processing failed due to an error: #{error}"
107
126
  when 'connection.listener.fetch_loop.error'
@@ -128,18 +128,21 @@ module Karafka
128
128
  histogram('consumer.consumption_lag', metadata.consumption_lag, tags: tags)
129
129
  end
130
130
 
131
- # @param event [Karafka::Core::Monitoring::Event]
132
- def on_consumer_revoked(event)
133
- tags = default_tags + consumer_tags(event.payload[:caller])
134
-
135
- count('consumer.revoked', 1, tags: tags)
136
- end
137
-
138
- # @param event [Karafka::Core::Monitoring::Event]
139
- def on_consumer_shutdown(event)
140
- tags = default_tags + consumer_tags(event.payload[:caller])
141
-
142
- count('consumer.shutdown', 1, tags: tags)
131
+ {
132
+ revoked: :revoked,
133
+ shutdown: :shutdown,
134
+ ticked: :tick
135
+ }.each do |after, name|
136
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
137
+ # Keeps track of user code execution
138
+ #
139
+ # @param event [Karafka::Core::Monitoring::Event]
140
+ def on_consumer_#{after}(event)
141
+ tags = default_tags + consumer_tags(event.payload[:caller])
142
+
143
+ count('consumer.#{name}', 1, tags: tags)
144
+ end
145
+ RUBY
143
146
  end
144
147
 
145
148
  # Worker related metrics
@@ -15,6 +15,14 @@ module Karafka
15
15
  # data would be processed, but process itself would still be active. This listener allows
16
16
  # for defining of a ttl that gets bumped on each poll loop and before and after processing
17
17
  # of a given messages batch.
18
+ #
19
+ # @note This listener will bind itself only when Karafka will actually attempt to start
20
+ # and moves from initializing to running. Before that, the TCP server will NOT be active.
21
+ # This is done on purpose to mitigate a case where users would subscribe this listener
22
+ # in `karafka.rb` without checking the recommendations of conditional assignment.
23
+ #
24
+ # @note In case of usage within an embedding with Puma, you need to select different port
25
+ # then the one used by Puma itself.
18
26
  class LivenessListener
19
27
  include ::Karafka::Core::Helpers::Time
20
28
 
@@ -40,12 +48,18 @@ module Karafka
40
48
  consuming_ttl: 5 * 60 * 1_000,
41
49
  polling_ttl: 5 * 60 * 1_000
42
50
  )
43
- @server = TCPServer.new(*[hostname, port].compact)
51
+ @hostname = hostname
52
+ @port = port
44
53
  @polling_ttl = polling_ttl
45
54
  @consuming_ttl = consuming_ttl
46
55
  @mutex = Mutex.new
47
56
  @pollings = {}
48
57
  @consumptions = {}
58
+ end
59
+
60
+ # @param _event [Karafka::Core::Monitoring::Event]
61
+ def on_app_running(_event)
62
+ @server = TCPServer.new(*[@hostname, @port].compact)
49
63
 
50
64
  Thread.new do
51
65
  loop do
@@ -54,42 +68,37 @@ module Karafka
54
68
  end
55
69
  end
56
70
 
57
- # Tick on each fetch
58
- # @param _event [Karafka::Core::Monitoring::Event]
59
- def on_connection_listener_fetch_loop(_event)
60
- mark_polling_tick
61
- end
62
-
63
- # Tick on starting work
64
- # @param _event [Karafka::Core::Monitoring::Event]
65
- def on_consumer_consume(_event)
66
- mark_consumption_tick
67
- end
68
-
69
- # Tick on finished work
70
- # @param _event [Karafka::Core::Monitoring::Event]
71
- def on_consumer_consumed(_event)
72
- clear_consumption_tick
73
- end
74
-
71
+ # Stop the http server when we stop the process
75
72
  # @param _event [Karafka::Core::Monitoring::Event]
76
- def on_consumer_revoke(_event)
77
- mark_consumption_tick
73
+ def on_app_stopped(_event)
74
+ @server.close
78
75
  end
79
76
 
77
+ # Tick on each fetch
80
78
  # @param _event [Karafka::Core::Monitoring::Event]
81
- def on_consumer_revoked(_event)
82
- clear_consumption_tick
79
+ def on_connection_listener_fetch_loop(_event)
80
+ mark_polling_tick
83
81
  end
84
82
 
85
- # @param _event [Karafka::Core::Monitoring::Event]
86
- def on_consumer_shutting_down(_event)
87
- mark_consumption_tick
88
- end
83
+ {
84
+ consume: :consumed,
85
+ revoke: :revoked,
86
+ shutting_down: :shutdown,
87
+ tick: :ticked
88
+ }.each do |before, after|
89
+ class_eval <<~RUBY, __FILE__, __LINE__ + 1
90
+ # Tick on starting work
91
+ # @param _event [Karafka::Core::Monitoring::Event]
92
+ def on_consumer_#{before}(_event)
93
+ mark_consumption_tick
94
+ end
89
95
 
90
- # @param _event [Karafka::Core::Monitoring::Event]
91
- def on_consumer_shutdown(_event)
92
- clear_consumption_tick
96
+ # Tick on finished work
97
+ # @param _event [Karafka::Core::Monitoring::Event]
98
+ def on_consumer_#{after}(_event)
99
+ clear_consumption_tick
100
+ end
101
+ RUBY
93
102
  end
94
103
 
95
104
  # @param _event [Karafka::Core::Monitoring::Event]
@@ -98,12 +107,6 @@ module Karafka
98
107
  clear_polling_tick
99
108
  end
100
109
 
101
- # Stop the http server when we stop the process
102
- # @param _event [Karafka::Core::Monitoring::Event]
103
- def on_app_stopped(_event)
104
- @server.close
105
- end
106
-
107
110
  private
108
111
 
109
112
  # Wraps the logic with a mutex
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This Karafka component is a Pro component under a commercial license.
4
+ # This Karafka component is NOT licensed under LGPL.
5
+ #
6
+ # All of the commercial components are present in the lib/karafka/pro directory of this
7
+ # repository and their usage requires commercial license agreement.
8
+ #
9
+ # Karafka has also commercial-friendly license, commercial support and commercial components.
10
+ #
11
+ # By sending a pull request to the pro components, you are agreeing to transfer the copyright of
12
+ # your code to Maciej Mensfeld.
13
+
14
+ module Karafka
15
+ module Pro
16
+ # Extra methods always used in the base consumer in the pro mode
17
+ #
18
+ # We do not define those methods as part of the strategies flows, because they are injected
19
+ # (strategies) on singletons and often used only in one of the strategy variants
20
+ #
21
+ # Methods here are suppose to be always available or are expected to be redefined
22
+ module BaseConsumer
23
+ # Runs the on-schedule tick periodic operations
24
+ # This method is an alias but is part of the naming convention used for other flows, this
25
+ # is why we do not reference the `handle_before_schedule_tick` directly
26
+ def on_before_schedule_tick
27
+ handle_before_schedule_tick
28
+ end
29
+
30
+ # Used by the executor to trigger consumer tick
31
+ # @private
32
+ def on_tick
33
+ handle_tick
34
+ rescue StandardError => e
35
+ Karafka.monitor.instrument(
36
+ 'error.occurred',
37
+ error: e,
38
+ caller: self,
39
+ type: 'consumer.tick.error'
40
+ )
41
+ end
42
+
43
+ # By default we do nothing when ticking
44
+ def tick; end
45
+ end
46
+ end
47
+ end