karafka-web 0.7.8 → 0.7.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d46244304483184c3be59a0686497a9f948e9b666dccf00961b560e60db4655
4
- data.tar.gz: 329686ce548063787fe06290d67650793ebef6c014f43b753780ad120671a8b1
3
+ metadata.gz: '0806cac6cd5ba083c727f4737a5bacbc6fb51a45229043745e401c3f5ccfd120'
4
+ data.tar.gz: f6f5743e8fe1b32eec5c126f81d8ed4bcb0501569c050b721a238388d608a7aa
5
5
  SHA512:
6
- metadata.gz: 5a18a3c23f63382c6c41dc5ac7f82f893bc14a55e7ec68af9cf16da0f47a45aee77ca9626973570cb9d6abe9355e0712f117424e00619b7b0198748c3bfbeb55
7
- data.tar.gz: f639bd90ca21c09fcd798fc289079cafeb9c752d261ecf88df9762e347df738bf260c658f0f15b3b08c3708daf091217c0159d85ac975380463a65a45d876d0b
6
+ metadata.gz: a70b5779abaa3440ffb85f8d735edf6a96723ab08c0c52a982c3ac09331d4a459053de0fcf4767bd79631d0314efe9d3a13949639d1b2ee62f88cda6e6519dbb
7
+ data.tar.gz: 2ab8bc6927e8e5d0cf6ef63e2be932322eeec8d0f668c7a144b61d5dfc3ceae74a758dcd58f32deac4ccf42c4cad1d799e7df4f5c0b0bbb0494b245362104262
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,6 +1,8 @@
1
1
  name: ci
2
2
 
3
- concurrency: ci-${{ github.ref }}
3
+ concurrency:
4
+ group: ${{ github.workflow }}-${{ github.ref }}
5
+ cancel-in-progress: true
4
6
 
5
7
  on:
6
8
  pull_request:
data/CHANGELOG.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # Karafka Web changelog
2
2
 
3
+ ## 0.7.10 (2023-10-31)
4
+ - [Fix] Max LSO chart does not work as expected (#201)
5
+
6
+ ## 0.7.9 (2023-10-25)
7
+ - [Enhancement] Allow for `Karafka::Web.producer` reconfiguration from the default (`Karafka.producer`).
8
+ - [Change] Rely on `karafka-core` `>=` `2.2.4` to support lazy loaded custom web producer.
9
+
3
10
  ## 0.7.8 (2023-10-24)
4
11
  - [Enhancement] Support transactional producer usage with Web UI.
5
- - [Fix] Fix a bug where critical errors (like `IRB::Abort`) would not abort the ongoing transaction.
6
12
  - [Fix] Prevent a scenario where an ongoing transactional producer would have stats emitted and an error that could not have been dispatched because of the transaction, creating a dead-lock.
7
13
  - [Fix] Make sure that the `recent` displays the most recent non-compacted, non-system message.
8
14
  - [Fix] Improve the `recent` message display to compensate for aborted transactions.
data/Gemfile.lock CHANGED
@@ -1,10 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- karafka-web (0.7.8)
4
+ karafka-web (0.7.10)
5
5
  erubi (~> 1.4)
6
6
  karafka (>= 2.2.9, < 3.0.0)
7
- karafka-core (>= 2.2.2, < 3.0.0)
7
+ karafka-core (>= 2.2.4, < 3.0.0)
8
8
  roda (~> 3.68, >= 3.69)
9
9
  tilt (~> 2.0)
10
10
 
@@ -40,7 +40,7 @@ GEM
40
40
  karafka-core (>= 2.2.2, < 2.3.0)
41
41
  waterdrop (>= 2.6.10, < 3.0.0)
42
42
  zeitwerk (~> 2.3)
43
- karafka-core (2.2.3)
43
+ karafka-core (2.2.4)
44
44
  concurrent-ruby (>= 1.1)
45
45
  karafka-rdkafka (>= 0.13.6, < 0.14.0)
46
46
  karafka-rdkafka (0.13.6)
data/karafka-web.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.add_dependency 'erubi', '~> 1.4'
20
20
  spec.add_dependency 'karafka', '>= 2.2.9', '< 3.0.0'
21
- spec.add_dependency 'karafka-core', '>= 2.2.2', '< 3.0.0'
21
+ spec.add_dependency 'karafka-core', '>= 2.2.4', '< 3.0.0'
22
22
  spec.add_dependency 'roda', '~> 3.68', '>= 3.69'
23
23
  spec.add_dependency 'tilt', '~> 2.0'
24
24
 
@@ -11,6 +11,17 @@ module Karafka
11
11
  # This is used both in the processing for eviction and in the UI
12
12
  setting :ttl, default: 30_000
13
13
 
14
+ # Producer for the Web UI. By default it is a `Karafka.producer`, however it may be
15
+ # overwritten if we want to use a separate instance in case of heavy usage of the
16
+ # transactional producer as a default. In cases like this, Karafka may not be able to report
17
+ # data because it uses this producer and it may be locked because of the transaction in a
18
+ # user space.
19
+ setting(
20
+ :producer,
21
+ constructor: -> { ::Karafka.producer },
22
+ lazy: true
23
+ )
24
+
14
25
  # Topics naming - used for processing and UI
15
26
  setting :topics do
16
27
  # All the errors encountered will be dispatched to this topic for inspection
@@ -41,11 +52,13 @@ module Karafka
41
52
  setting :scheduler, default: Tracking::Scheduler.new
42
53
 
43
54
  setting :consumers do
44
- # Reports the metrics collected in the sampler
55
+ # Reports the metrics collected in the consumer sampler
45
56
  setting :reporter, default: Tracking::Consumers::Reporter.new
46
57
 
58
+ # Samples for fetching and storing metrics samples about the consumer process
47
59
  setting :sampler, default: Tracking::Consumers::Sampler.new
48
60
 
61
+ # Listeners needed for the Web UI to track consumer related changes
49
62
  setting :listeners, default: [
50
63
  Tracking::Consumers::Listeners::Status.new,
51
64
  Tracking::Consumers::Listeners::Errors.new,
@@ -57,10 +70,13 @@ module Karafka
57
70
  end
58
71
 
59
72
  setting :producers do
73
+ # Reports the metrics collected in the producer sampler
60
74
  setting :reporter, default: Tracking::Producers::Reporter.new
61
75
 
76
+ # Sampler for errors from producers
62
77
  setting :sampler, default: Tracking::Producers::Sampler.new
63
78
 
79
+ # Listeners needed for the Web UI to track producers related stuff
64
80
  setting :listeners, default: [
65
81
  Tracking::Producers::Listeners::Errors.new
66
82
  ]
@@ -55,7 +55,7 @@ module Karafka
55
55
  exists('consumers state')
56
56
  else
57
57
  creating('consumers state')
58
- ::Karafka.producer.produce_sync(
58
+ ::Karafka::Web.producer.produce_sync(
59
59
  topic: Karafka::Web.config.topics.consumers.states,
60
60
  key: Karafka::Web.config.topics.consumers.states,
61
61
  payload: DEFAULT_STATE.to_json
@@ -67,7 +67,7 @@ module Karafka
67
67
  exists('consumers metrics')
68
68
  else
69
69
  creating('consumers metrics')
70
- ::Karafka.producer.produce_sync(
70
+ ::Karafka::Web.producer.produce_sync(
71
71
  topic: Karafka::Web.config.topics.consumers.metrics,
72
72
  key: Karafka::Web.config.topics.consumers.metrics,
73
73
  payload: DEFAULT_METRICS.merge(dispatched_at: Time.now.to_f).to_json
@@ -11,6 +11,7 @@ module Karafka
11
11
  def call
12
12
  extend_routing
13
13
  subscribe_to_monitor
14
+ subscribe_to_close_web_producer
14
15
  end
15
16
 
16
17
  private
@@ -71,9 +72,28 @@ module Karafka
71
72
  ::Karafka.monitor.subscribe(listener)
72
73
  end
73
74
 
74
- # Installs all the producer related listeners
75
+ # Installs all the producer related listeners into Karafka default listener and
76
+ # into Karafka::Web listener in case it would be different than the Karafka one
75
77
  ::Karafka::Web.config.tracking.producers.listeners.each do |listener|
76
78
  ::Karafka.producer.monitor.subscribe(listener)
79
+
80
+ # Do not instrument twice in case only one default producer is used
81
+ next if ::Karafka.producer == ::Karafka::Web.producer
82
+
83
+ ::Karafka::Web.producer.monitor.subscribe(listener)
84
+ end
85
+ end
86
+
87
+ # In most cases we want to close the producer if possible.
88
+ # While we cannot do it easily in user processes and we should rely on WaterDrop
89
+ # finalization logic, we can do it in `karafka server` on terminate
90
+ #
91
+ # In other places, this producer anyhow should not be used.
92
+ def subscribe_to_close_web_producer
93
+ ::Karafka::App.monitor.subscribe('app.terminated') do
94
+ # If Web producer is the same as `Karafka.producer` it will do nothing as you can
95
+ # call `#close` multiple times without side effects
96
+ ::Karafka::Web.producer.close
77
97
  end
78
98
  end
79
99
  end
@@ -114,7 +114,7 @@ module Karafka
114
114
  def flush
115
115
  @flushed_at = monotonic_now
116
116
 
117
- producer.produce_many_async(
117
+ ::Karafka::Web.producer.produce_many_async(
118
118
  [
119
119
  {
120
120
  topic: Karafka::Web.config.topics.consumers.states,
@@ -107,9 +107,18 @@ module Karafka
107
107
 
108
108
  # Last stable offsets freeze durations - we pick the max freeze to indicate
109
109
  # the longest open transaction that potentially may be hanging
110
- ls_offsets_fd = partitions_data
111
- .map { |p_details| p_details.fetch(:ls_offset_fd, 0) }
112
- .reject(&:negative?)
110
+ # We select only those partitions for which LSO != HO as in any other case this
111
+ # just means we've reached the end of data and ls may freeze because there is no
112
+ # more data flowing. Such cases should not be reported as ls offset freezes because
113
+ # there is no more data to be processed and can grow until more data is present
114
+ # this does not indicate "bad" freezing that we are interested in
115
+ ls_offsets_fds = partitions_data.map do |p_details|
116
+ next if p_details.fetch(:ls_offset, 0) == p_details.fetch(:hi_offset, 0)
117
+
118
+ ls_offset_fd = p_details.fetch(:ls_offset_fd, 0)
119
+
120
+ ls_offset_fd.negative? ? nil : ls_offset_fd
121
+ end
113
122
 
114
123
  cgs[group_name] ||= {}
115
124
  cgs[group_name][topic_name] = {
@@ -119,7 +128,7 @@ module Karafka
119
128
  # Take max last stable offset duration without any change. This can
120
129
  # indicate a hanging transaction, because the offset will not move forward
121
130
  # and will stay with a growing freeze duration when stuck
122
- ls_offset_fd: ls_offsets_fd.max || 0
131
+ ls_offset_fd: ls_offsets_fds.compact.max || 0
123
132
  }
124
133
  end
125
134
 
@@ -135,9 +135,9 @@ module Karafka
135
135
  # slowdown any processing.
136
136
  def produce(messages)
137
137
  if messages.count >= PRODUCE_SYNC_THRESHOLD
138
- ::Karafka.producer.produce_many_sync(messages)
138
+ ::Karafka::Web.producer.produce_many_sync(messages)
139
139
  else
140
- ::Karafka.producer.produce_many_async(messages)
140
+ ::Karafka::Web.producer.produce_many_async(messages)
141
141
  end
142
142
  # Since we run this in a background thread, there may be a case upon shutdown, where the
143
143
  # producer is closed right before a potential dispatch. It is not worth dealing with this
@@ -83,9 +83,9 @@ module Karafka
83
83
  # slowdown any processing.
84
84
  def produce(messages)
85
85
  if messages.count >= PRODUCE_SYNC_THRESHOLD
86
- ::Karafka.producer.produce_many_sync(messages)
86
+ ::Karafka::Web.producer.produce_many_sync(messages)
87
87
  else
88
- ::Karafka.producer.produce_many_async(messages)
88
+ ::Karafka::Web.producer.produce_many_async(messages)
89
89
  end
90
90
  # Since we run this in a background thread, there may be a case upon shutdown, where the
91
91
  # producer is closed right before a potential dispatch. It is not worth dealing with this
@@ -14,8 +14,8 @@ module Karafka
14
14
  #
15
15
  # @return [Boolean]
16
16
  def active?
17
- return false unless ::Karafka::App.producer
18
- return false unless ::Karafka::App.producer.status.active?
17
+ return false unless ::Karafka::Web.producer
18
+ return false unless ::Karafka::Web.producer.status.active?
19
19
 
20
20
  true
21
21
  end
@@ -76,20 +76,11 @@ module Karafka
76
76
  topic_without_cg = topic.split('[').first
77
77
 
78
78
  metrics.each do |current|
79
- ls_offset = current.last[:ls_offset] || 0
80
79
  ls_offset_fd = current.last[:ls_offset_fd] || 0
81
- hi_offset = current.last[:hi_offset] || 0
82
80
 
83
81
  # We convert this to seconds from milliseconds due to our Web UI precision
84
82
  # Reporting is in ms for consistency
85
83
  normalized_fd = (ls_offset_fd / 1_000).round
86
- # In case ls_offset and hi_offset are the same, it means we're reached eof
87
- # and we just don't have more data. In cases like this, LSO freeze duration
88
- # will grow because LSO will remain unchanged, but it does not mean it is
89
- # frozen. It means there is just no more data in the topic partition
90
- # This means we need to nullify this case, otherwise it would report, that
91
- # lso is hanging.
92
- normalized_fd = 0 if ls_offset == hi_offset
93
84
 
94
85
  topics[topic_without_cg][current.first] << normalized_fd
95
86
  end
@@ -28,7 +28,7 @@ module Karafka
28
28
  def republish(topic_id, partition_id, offset)
29
29
  message = Ui::Models::Message.find(topic_id, partition_id, offset)
30
30
 
31
- delivery = ::Karafka.producer.produce_sync(
31
+ delivery = ::Karafka::Web.producer.produce_sync(
32
32
  topic: topic_id,
33
33
  partition: partition_id,
34
34
  payload: message.raw_payload,
@@ -3,6 +3,6 @@
3
3
  module Karafka
4
4
  module Web
5
5
  # Current gem version
6
- VERSION = '0.7.8'
6
+ VERSION = '0.7.10'
7
7
  end
8
8
  end
data/lib/karafka/web.rb CHANGED
@@ -13,6 +13,12 @@ module Karafka
13
13
  # Karafka Web UI + Karafka web monitoring
14
14
  module Web
15
15
  class << self
16
+ # @return [WaterDrop::Producer, nil] waterdrop messages producer or nil if not yet fully
17
+ # initialized. It may not be fully initialized until the configuration is done
18
+ def producer
19
+ @producer ||= Web.config.producer
20
+ end
21
+
16
22
  # @return [String] root path of this gem
17
23
  def gem_root
18
24
  Pathname.new(File.expand_path('../..', __dir__))
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: karafka-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.8
4
+ version: 0.7.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maciej Mensfeld
@@ -35,7 +35,7 @@ cert_chain:
35
35
  AnG1dJU+yL2BK7vaVytLTstJME5mepSZ46qqIJXMuWob/YPDmVaBF39TDSG9e34s
36
36
  msG3BiCqgOgHAnL23+CN3Rt8MsuRfEtoTKpJVcCfoEoNHOkc
37
37
  -----END CERTIFICATE-----
38
- date: 2023-10-24 00:00:00.000000000 Z
38
+ date: 2023-10-31 00:00:00.000000000 Z
39
39
  dependencies:
40
40
  - !ruby/object:Gem::Dependency
41
41
  name: erubi
@@ -77,7 +77,7 @@ dependencies:
77
77
  requirements:
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: 2.2.2
80
+ version: 2.2.4
81
81
  - - "<"
82
82
  - !ruby/object:Gem::Version
83
83
  version: 3.0.0
@@ -87,7 +87,7 @@ dependencies:
87
87
  requirements:
88
88
  - - ">="
89
89
  - !ruby/object:Gem::Version
90
- version: 2.2.2
90
+ version: 2.2.4
91
91
  - - "<"
92
92
  - !ruby/object:Gem::Version
93
93
  version: 3.0.0
metadata.gz.sig CHANGED
Binary file