karafka 2.0.13 → 2.0.15
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.github/workflows/ci.yml +4 -4
- data/.rspec +2 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile.lock +1 -1
- data/bin/integrations +7 -6
- data/lib/karafka/admin.rb +4 -1
- data/lib/karafka/connection/client.rb +2 -4
- data/lib/karafka/embedded.rb +23 -0
- data/lib/karafka/instrumentation/vendors/datadog/dashboard.json +1 -1
- data/lib/karafka/instrumentation/vendors/datadog/listener.rb +23 -1
- data/lib/karafka/pro/processing/partitioner.rb +11 -16
- data/lib/karafka/process.rb +7 -0
- data/lib/karafka/server.rb +9 -2
- data/lib/karafka/status.rb +3 -0
- data/lib/karafka/time_trackers/pause.rb +28 -9
- data/lib/karafka/time_trackers/poll.rb +2 -1
- data/lib/karafka/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +3 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79c991a988c67b681c8bdf16d06d61b3781be5bbc070d23a1258ea0152058d41
|
4
|
+
data.tar.gz: 478d2155761e7fa4bb6b766a5fd598f3524b5810edddc36229185bb9ce396c3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d9a3ba7e201947f0ced657eb61aa8f4af348f70a85167a9194f34039d070248551aa3a09d270930ccac399d774fc89305a4f2bc36da715066cd789997fbb40d9
|
7
|
+
data.tar.gz: b5cf1015aa851c7ab78fa89e2b2317085c18f24c8b5a03f5b82c8c3c7ac2ef95fe6a1888defc97f62492c107c2b0b2cd1b72bbe5811fb99dd92e39e93f912608
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/.github/workflows/ci.yml
CHANGED
@@ -18,7 +18,7 @@ jobs:
|
|
18
18
|
strategy:
|
19
19
|
fail-fast: false
|
20
20
|
steps:
|
21
|
-
- uses: actions/checkout@
|
21
|
+
- uses: actions/checkout@v3
|
22
22
|
with:
|
23
23
|
fetch-depth: 0
|
24
24
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
39
39
|
strategy:
|
40
40
|
fail-fast: false
|
41
41
|
steps:
|
42
|
-
- uses: actions/checkout@
|
42
|
+
- uses: actions/checkout@v3
|
43
43
|
with:
|
44
44
|
fetch-depth: 0
|
45
45
|
- name: Run Coditsu
|
@@ -64,7 +64,7 @@ jobs:
|
|
64
64
|
- ruby: '3.1'
|
65
65
|
coverage: 'true'
|
66
66
|
steps:
|
67
|
-
- uses: actions/checkout@
|
67
|
+
- uses: actions/checkout@v3
|
68
68
|
- name: Install package dependencies
|
69
69
|
run: "[ -e $APT_DEPS ] || sudo apt-get install -y --no-install-recommends $APT_DEPS"
|
70
70
|
|
@@ -97,7 +97,7 @@ jobs:
|
|
97
97
|
- ruby: '3.1'
|
98
98
|
coverage: 'true'
|
99
99
|
steps:
|
100
|
-
- uses: actions/checkout@
|
100
|
+
- uses: actions/checkout@v3
|
101
101
|
- name: Install package dependencies
|
102
102
|
run: "[ -e $APT_DEPS ] || sudo apt-get install -y --no-install-recommends $APT_DEPS"
|
103
103
|
|
data/.rspec
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# Karafka framework changelog
|
2
2
|
|
3
|
+
## 2.0.15 (2022-10-20)
|
4
|
+
- Sanitize admin config prior to any admin action.
|
5
|
+
- Make messages partitioner outcome for virtual partitions consistently distributed in regards to concurrency.
|
6
|
+
- Improve DataDog/StatsD metrics reporting by reporting per topic partition lags and trends.
|
7
|
+
- Replace synchronous offset commit with async on resuming paused partition (#1087).
|
8
|
+
|
9
|
+
## 2.0.14 (2022-10-16)
|
10
|
+
- Prevent consecutive stop signals from starting multiple supervision shutdowns.
|
11
|
+
- Provide `Karafka::Embedded` to simplify the start/stop process when running Karafka from within other process (Puma, Sidekiq, etc).
|
12
|
+
- Fix a race condition when un-pausing a long-running-job exactly upon listener resuming would crash the listener loop (#1072).
|
13
|
+
|
3
14
|
## 2.0.13 (2022-10-14)
|
4
15
|
- Early exit upon attempts to commit current or earlier offset twice.
|
5
16
|
- Add more integration specs covering edge cases.
|
data/Gemfile.lock
CHANGED
data/bin/integrations
CHANGED
@@ -24,7 +24,7 @@ ROOT_PATH = Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), '../
|
|
24
24
|
# When the value is high, there's a problem with thread allocation on Github CI, tht is why
|
25
25
|
# we limit it. Locally we can run a lot of those, as many of them have sleeps and do not use a lot
|
26
26
|
# of CPU
|
27
|
-
CONCURRENCY = ENV.key?('CI') ?
|
27
|
+
CONCURRENCY = ENV.key?('CI') ? 4 : Etc.nprocessors * 2
|
28
28
|
|
29
29
|
# How may bytes do we want to keep from the stdout in the buffer for when we need to print it
|
30
30
|
MAX_BUFFER_OUTPUT = 51_200
|
@@ -39,10 +39,10 @@ class Scenario
|
|
39
39
|
# This includes exactly those
|
40
40
|
EXIT_CODES = {
|
41
41
|
default: [0],
|
42
|
-
'consumption/
|
43
|
-
'shutdown/
|
44
|
-
'shutdown/
|
45
|
-
'shutdown/
|
42
|
+
'consumption/worker_critical_error_behaviour_spec.rb' => [0, 2].freeze,
|
43
|
+
'shutdown/on_hanging_jobs_and_a_shutdown_spec.rb' => [2].freeze,
|
44
|
+
'shutdown/on_hanging_on_shutdown_job_and_a_shutdown_spec.rb' => [2].freeze,
|
45
|
+
'shutdown/on_hanging_listener_and_shutdown_spec.rb' => [2].freeze
|
46
46
|
}.freeze
|
47
47
|
|
48
48
|
private_constant :MAX_RUN_TIME, :EXIT_CODES
|
@@ -202,7 +202,7 @@ class Scenario
|
|
202
202
|
end
|
203
203
|
|
204
204
|
# Load all the specs
|
205
|
-
specs = Dir[ROOT_PATH.join('spec/integrations
|
205
|
+
specs = Dir[ROOT_PATH.join('spec/integrations/**/*_spec.rb')]
|
206
206
|
|
207
207
|
# If filters is provided, apply
|
208
208
|
# Allows to provide several filters one after another and applies all of them
|
@@ -210,6 +210,7 @@ ARGV.each do |filter|
|
|
210
210
|
specs.delete_if { |name| !name.include?(filter) }
|
211
211
|
end
|
212
212
|
|
213
|
+
|
213
214
|
raise ArgumentError, "No integration specs with filters: #{ARGV.join(', ')}" if specs.empty?
|
214
215
|
|
215
216
|
# Randomize order
|
data/lib/karafka/admin.rb
CHANGED
@@ -52,7 +52,10 @@ module Karafka
|
|
52
52
|
|
53
53
|
# Creates admin instance and yields it. After usage it closes the admin instance
|
54
54
|
def with_admin
|
55
|
-
|
55
|
+
# Admin needs a producer config
|
56
|
+
config = Karafka::Setup::AttributesMap.producer(Karafka::App.config.kafka.dup)
|
57
|
+
|
58
|
+
admin = ::Rdkafka::Config.new(config).admin
|
56
59
|
result = yield(admin)
|
57
60
|
result
|
58
61
|
ensure
|
@@ -179,10 +179,8 @@ module Karafka
|
|
179
179
|
|
180
180
|
return if @closed
|
181
181
|
|
182
|
-
#
|
183
|
-
|
184
|
-
# We can skip performance penalty since resuming should not happen too often
|
185
|
-
internal_commit_offsets(async: false)
|
182
|
+
# We now commit offsets on rebalances, thus we can do it async just to make sure
|
183
|
+
internal_commit_offsets(async: true)
|
186
184
|
|
187
185
|
# If we were not able, let's try to reuse the one we have (if we have)
|
188
186
|
tpl = topic_partition_list(topic, partition) || @paused_tpls[topic][partition]
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Karafka
|
4
|
+
# Allows to start and stop Karafka as part of a different process
|
5
|
+
module Embedded
|
6
|
+
class << self
|
7
|
+
# Starts Karafka without supervision and without ownership of signals in a background thread
|
8
|
+
# so it won't interrupt other things running
|
9
|
+
def start
|
10
|
+
Thread.new { Karafka::Server.start }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Stops Karafka upon any event
|
14
|
+
#
|
15
|
+
# @note This method is blocking because we want to wait until Karafka is stopped with final
|
16
|
+
# process shutdown
|
17
|
+
def stop
|
18
|
+
# Stop needs to be blocking to wait for all the things to finalize
|
19
|
+
Karafka::Server.stop
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
{"title":"Karafka monitoring dashboard","description":"","widgets":[{"id":7444969424381053,"definition":{"title":"Stability & errors","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":8304008422587936,"definition":{"title":"Client connects and disconnects","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Connects","formula":"query1"},{"alias":"Disconnects","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.connection.connects{*} by {host}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.connection.disconnects{*} by {host}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"bars"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":3722865443336921,"definition":{"title":"Errors encountered (any)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"in-karafka errors","formula":"query1"},{"alias":"librdkafka consume errors","formula":"query2"},{"alias":"librdkafka receive errors","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{*} by {type}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consume.errors{*}.as_count()","data_source":"metrics","name":"query2"},{"query":"sum:karafka.receive.errors{*}.as_count()","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":5477381252952760,"definition":{"title":"Processing errors","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{type:consumer.consume.error} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}},{"id":2357301680769076,"definition":{"title":"Processing errors rate per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"% error rate per topic","formula":"(query1 / (query1 + query2)) * 100"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{type:consumer.consume.error} by {topic,partition}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*} by {topic,partition}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"bars"}]},"layout":{"x":0,"y":2,"width":4,"height":2}},{"id":3902930069982135,"definition":{"title":"Batches successful vs failures","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Successfully processed batch","formula":"query1"},{"alias":"Batch processing with error","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"},{"query":"avg:karafka.error_occurred{type:consumer.consume.error} by {partition,topic}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":2,"width":4,"height":2}},{"id":718749162159145,"definition":{"title":"Consumer instances revocations and shutdowns","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Consumer instances revokations","formula":"query1"},{"alias":"Consumer instances shutdowns","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.revoked{*}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.shutdown{*}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":2,"width":4,"height":2}}]},"layout":{"x":0,"y":0,"width":12,"height":5}},{"id":5988438511387100,"definition":{"title":"Workers poll","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":8769294644934352,"definition":{"title":"Enqueued jobs","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Enqueued jobs","formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.enqueued_jobs.avg{*}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":2714502141463873,"definition":{"title":"Workers usage","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Busy workers (p95)","formula":"query1"},{"alias":"Total workers","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.processing.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.worker.total_threads{*}","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":5370086629441984,"definition":{"title":"Workers % utilization","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"% workers utilization","formula":"(query1 / query2) * 100"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.processing.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.worker.total_threads{*}","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}}]},"layout":{"x":0,"y":5,"width":12,"height":3}},{"id":8544040083223278,"definition":{"title":"Throughput ","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":3740207481939733,"definition":{"title":"Offset lag changes","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"derivative(query1)"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.offset{*} by {topic,partition}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":6319110548544878,"definition":{"title":"Batches processed per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":6232784865331443,"definition":{"title":"Messages consumed per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Messages consumed","formula":"query1"},{"alias":"Average batch size","formula":"query1 / query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.messages{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}},{"id":2321394598982770,"definition":{"title":"Consumption lag (in seconds)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Consumption lag in s (max)","formula":"query2 / 1000"},{"alias":"Consumption lag in s (avg)","formula":"query3 / 1000"},{"alias":"Consumption lag in s (p95)","formula":"query1 / 1000"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.consumption_lag.max{*}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.consumption_lag.avg{*}","data_source":"metrics","name":"query3"},{"query":"max:karafka.consumer.consumption_lag.95percentile{*}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":2,"width":4,"height":2}},{"id":1062074781483741,"definition":{"title":"Processing lag (in ms)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Processing lag in ms (p95)","formula":"query1"},{"alias":"Processing lag in ms (max)","formula":"query2"},{"alias":"Processing lag in ms (avg)","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.processing_lag.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"max:karafka.consumer.processing_lag.max{*}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.processing_lag.avg{*}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":2,"width":4,"height":2}},{"id":7497794728674267,"definition":{"title":"Batch processing time","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"},{"formula":"query2"},{"formula":"query3"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.consumed.time_taken.95percentile{*} by {topic,partition}","data_source":"metrics","name":"query1"},{"query":"max:karafka.consumer.consumed.time_taken.max{*} by {topic,partition}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.consumed.time_taken.avg{*} by {topic,partition}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":2,"width":4,"height":2}},{"id":4192833027984161,"definition":{"title":"Batch size per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Batch size p95","formula":"query1"},{"alias":"Batch size avg","formula":"query2"},{"alias":"Batch size max","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batch_size.95percentile{*} by {partition,topic}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batch_size.avg{*} by {partition,topic}","data_source":"metrics","name":"query2"},{"query":"sum:karafka.consumer.batch_size.max{*} by {partition,topic}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":4,"width":4,"height":2}},{"id":4741598444771147,"definition":{"title":"Messages consumed overall","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Messages consumed","formula":"query1"},{"alias":"Average batch size","formula":"query1 / query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.messages{*}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":4,"width":4,"height":2}},{"id":4502534794102513,"definition":{"title":"Polling times (ms)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"time":{},"type":"timeseries","requests":[{"formulas":[{"alias":"p95 ms polling time","formula":"query1"},{"alias":"max ms polling time","formula":"query2"},{"alias":"average ms polling time","formula":"query3"}],"queries":[{"name":"query1","data_source":"metrics","query":"avg:karafka.listener.polling.time_taken.95percentile{*}"},{"name":"query2","data_source":"metrics","query":"avg:karafka.listener.polling.time_taken.max{*}"},{"name":"query3","data_source":"metrics","query":"avg:karafka.listener.polling.time_taken.avg{*}"}],"response_format":"timeseries","style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":4,"width":4,"height":2}}]},"layout":{"x":0,"y":0,"width":12,"height":7,"is_column_break":true}}],"template_variables":[],"layout_type":"ordered","is_read_only":false,"notify_list":[],"reflow_type":"fixed","id":"s3u-z47-i6u"}
|
1
|
+
{"title":"Karafka monitoring dashboard","description":"","widgets":[{"id":5988438511387100,"definition":{"title":"Workers poll","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":8769294644934352,"definition":{"title":"Enqueued jobs","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Enqueued jobs","formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.enqueued_jobs.avg{*}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":2714502141463873,"definition":{"title":"Workers usage","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Busy workers (p95)","formula":"query1"},{"alias":"Total workers","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.processing.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.worker.total_threads{*}","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":5370086629441984,"definition":{"title":"Workers % utilization","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"% workers utilization","formula":"(query1 / query2) * 100"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.worker.processing.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.worker.total_threads{*}","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}}]},"layout":{"x":0,"y":0,"width":12,"height":3}},{"id":7444969424381053,"definition":{"title":"Stability & errors","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":8304008422587936,"definition":{"title":"Client connects and disconnects","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Connects","formula":"query1"},{"alias":"Disconnects","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.connection.connects{*} by {host}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.connection.disconnects{*} by {host}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"bars"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":3722865443336921,"definition":{"title":"Errors encountered (any)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"in-karafka errors","formula":"query1"},{"alias":"librdkafka consume errors","formula":"query2"},{"alias":"librdkafka receive errors","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{*} by {type}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consume.errors{*}.as_count()","data_source":"metrics","name":"query2"},{"query":"sum:karafka.receive.errors{*}.as_count()","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":5477381252952760,"definition":{"title":"Processing errors","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{type:consumer.consume.error} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}},{"id":2357301680769076,"definition":{"title":"Processing errors rate per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"% error rate per topic","formula":"(query1 / (query1 + query2)) * 100"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.error_occurred{type:consumer.consume.error} by {topic,partition}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*} by {topic,partition}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"bars"}]},"layout":{"x":0,"y":2,"width":4,"height":2}},{"id":3902930069982135,"definition":{"title":"Batches successful vs failures","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Successfully processed batch","formula":"query1"},{"alias":"Batch processing with error","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"},{"query":"avg:karafka.error_occurred{type:consumer.consume.error} by {partition,topic}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":2,"width":4,"height":2}},{"id":718749162159145,"definition":{"title":"Consumer instances revocations and shutdowns","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Consumer instances revokations","formula":"query1"},{"alias":"Consumer instances shutdowns","formula":"query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.revoked{*}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.shutdown{*}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":2,"width":4,"height":2}}]},"layout":{"x":0,"y":3,"width":12,"height":5}},{"id":7288186528768428,"definition":{"title":"Topics overview","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":1533435157804573,"definition":{"title":"Topics lags","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"time":{},"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"queries":[{"name":"query1","data_source":"metrics","query":"avg:karafka.consumer.lags{*} by {partition,topic}"}],"response_format":"timeseries","style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":0,"width":6,"height":2}},{"id":1411506453982604,"definition":{"title":"Topics lag trends","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"time":{},"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"queries":[{"name":"query1","data_source":"metrics","query":"avg:karafka.consumer.lags_delta{*} by {partition,topic}"}],"response_format":"timeseries","style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":6,"y":0,"width":6,"height":2}}]},"layout":{"x":0,"y":0,"width":12,"height":3,"is_column_break":true}},{"id":8544040083223278,"definition":{"title":"Throughput ","type":"group","show_title":true,"layout_type":"ordered","widgets":[{"id":3740207481939733,"definition":{"title":"Offset lag changes","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"derivative(query1)"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.offset{*} by {topic,partition}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":0,"width":4,"height":2}},{"id":6319110548544878,"definition":{"title":"Batches processed per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":0,"width":4,"height":2}},{"id":6232784865331443,"definition":{"title":"Messages consumed per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Messages consumed","formula":"query1"},{"alias":"Average batch size","formula":"query1 / query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.messages{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*} by {partition,topic}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":0,"width":4,"height":2}},{"id":2321394598982770,"definition":{"title":"Consumption lag (in seconds)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Consumption lag in s (max)","formula":"query2 / 1000"},{"alias":"Consumption lag in s (avg)","formula":"query3 / 1000"},{"alias":"Consumption lag in s (p95)","formula":"query1 / 1000"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.consumption_lag.max{*}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.consumption_lag.avg{*}","data_source":"metrics","name":"query3"},{"query":"max:karafka.consumer.consumption_lag.95percentile{*}","data_source":"metrics","name":"query1"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":2,"width":4,"height":2}},{"id":1062074781483741,"definition":{"title":"Processing lag (in ms)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Processing lag in ms (p95)","formula":"query1"},{"alias":"Processing lag in ms (max)","formula":"query2"},{"alias":"Processing lag in ms (avg)","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.processing_lag.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"max:karafka.consumer.processing_lag.max{*}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.processing_lag.avg{*}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":2,"width":4,"height":2}},{"id":7497794728674267,"definition":{"title":"Batch processing time","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"formula":"query1"},{"formula":"query2"},{"formula":"query3"}],"response_format":"timeseries","queries":[{"query":"max:karafka.consumer.consumed.time_taken.95percentile{*} by {topic,partition}","data_source":"metrics","name":"query1"},{"query":"max:karafka.consumer.consumed.time_taken.max{*} by {topic,partition}","data_source":"metrics","name":"query2"},{"query":"max:karafka.consumer.consumed.time_taken.avg{*} by {topic,partition}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":2,"width":4,"height":2}},{"id":4192833027984161,"definition":{"title":"Batch size per topic","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Batch size p95","formula":"query1"},{"alias":"Batch size avg","formula":"query2"},{"alias":"Batch size max","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.batch_size.95percentile{*} by {partition,topic}","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batch_size.avg{*} by {partition,topic}","data_source":"metrics","name":"query2"},{"query":"sum:karafka.consumer.batch_size.max{*} by {partition,topic}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":0,"y":4,"width":4,"height":2}},{"id":4741598444771147,"definition":{"title":"Messages consumed overall","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"Messages consumed","formula":"query1"},{"alias":"Average batch size","formula":"query1 / query2"}],"response_format":"timeseries","queries":[{"query":"sum:karafka.consumer.messages{*}.as_count()","data_source":"metrics","name":"query1"},{"query":"sum:karafka.consumer.batches{*}.as_count()","data_source":"metrics","name":"query2"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":4,"y":4,"width":4,"height":2}},{"id":4502534794102513,"definition":{"title":"Polling times (ms)","title_size":"16","title_align":"left","show_legend":true,"legend_layout":"auto","legend_columns":["avg","min","max","value","sum"],"type":"timeseries","requests":[{"formulas":[{"alias":"p95 ms polling time","formula":"query1"},{"alias":"max ms polling time","formula":"query2"},{"alias":"average ms polling time","formula":"query3"}],"response_format":"timeseries","queries":[{"query":"avg:karafka.listener.polling.time_taken.95percentile{*}","data_source":"metrics","name":"query1"},{"query":"avg:karafka.listener.polling.time_taken.max{*}","data_source":"metrics","name":"query2"},{"query":"avg:karafka.listener.polling.time_taken.avg{*}","data_source":"metrics","name":"query3"}],"style":{"palette":"dog_classic","line_type":"solid","line_width":"normal"},"display_type":"line"}]},"layout":{"x":8,"y":4,"width":4,"height":2}}]},"layout":{"x":0,"y":3,"width":12,"height":7}}],"template_variables":[],"layout_type":"ordered","is_read_only":false,"notify_list":[],"reflow_type":"fixed","id":"s3u-z47-i6u"}
|
@@ -46,7 +46,11 @@ module Karafka
|
|
46
46
|
RdKafkaMetric.new(:count, :brokers, 'connection.disconnects', 'disconnects_d'),
|
47
47
|
RdKafkaMetric.new(:gauge, :brokers, 'network.latency.avg', %w[rtt avg]),
|
48
48
|
RdKafkaMetric.new(:gauge, :brokers, 'network.latency.p95', %w[rtt p95]),
|
49
|
-
RdKafkaMetric.new(:gauge, :brokers, 'network.latency.p99', %w[rtt p99])
|
49
|
+
RdKafkaMetric.new(:gauge, :brokers, 'network.latency.p99', %w[rtt p99]),
|
50
|
+
|
51
|
+
# Topics metrics
|
52
|
+
RdKafkaMetric.new(:gauge, :topics, 'consumer.lags', 'consumer_lag_stored'),
|
53
|
+
RdKafkaMetric.new(:gauge, :topics, 'consumer.lags_delta', 'consumer_lag_stored_d')
|
50
54
|
].freeze
|
51
55
|
|
52
56
|
configure
|
@@ -221,6 +225,24 @@ module Karafka
|
|
221
225
|
tags: default_tags + ["broker:#{broker_statistics['nodename']}"]
|
222
226
|
)
|
223
227
|
end
|
228
|
+
when :topics
|
229
|
+
statistics.fetch('topics').each do |topic_name, topic_values|
|
230
|
+
topic_values['partitions'].each do |partition_name, partition_statistics|
|
231
|
+
next if partition_name == '-1'
|
232
|
+
# Skip until lag info is available
|
233
|
+
next if partition_statistics['consumer_lag'] == -1
|
234
|
+
|
235
|
+
public_send(
|
236
|
+
metric.type,
|
237
|
+
metric.name,
|
238
|
+
partition_statistics.dig(*metric.key_location),
|
239
|
+
tags: default_tags + [
|
240
|
+
"topic:#{topic_name}",
|
241
|
+
"partition:#{partition_name}"
|
242
|
+
]
|
243
|
+
)
|
244
|
+
end
|
245
|
+
end
|
224
246
|
else
|
225
247
|
raise ArgumentError, metric.scope
|
226
248
|
end
|
@@ -25,28 +25,23 @@ module Karafka
|
|
25
25
|
# process the data. With one thread it is not worth partitioning the work as the work
|
26
26
|
# itself will be assigned to one thread (pointless work)
|
27
27
|
if ktopic.virtual_partitions? && ktopic.virtual_partitions.max_partitions > 1
|
28
|
-
# We need to reduce it to
|
28
|
+
# We need to reduce it to the max concurrency, so the group_id is not a direct effect
|
29
29
|
# of the end user action. Otherwise the persistence layer for consumers would cache
|
30
30
|
# it forever and it would cause memory leaks
|
31
|
-
groupings = messages
|
32
|
-
.group_by { |msg| ktopic.virtual_partitions.partitioner.call(msg) }
|
33
|
-
.values
|
34
|
-
|
35
|
-
# Reduce the number of virtual partitions to a size that matches the max_partitions
|
36
|
-
# As mentioned above we cannot use the partitioning keys directly as it could cause
|
37
|
-
# memory leaks
|
38
31
|
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
|
43
|
-
|
32
|
+
# This also needs to be consistent because the aggregation here needs to warrant, that
|
33
|
+
# the same partitioned message will always be assigned to the same virtual partition.
|
34
|
+
# Otherwise in case of a window aggregation with VP spanning across several polls, the
|
35
|
+
# data could not be complete.
|
36
|
+
groupings = messages.group_by do |msg|
|
37
|
+
key = ktopic.virtual_partitions.partitioner.call(msg).to_s.sum
|
44
38
|
|
45
|
-
|
46
|
-
groupings << (groupings.pop + groupings.pop).sort_by!(&:offset)
|
39
|
+
key % ktopic.virtual_partitions.max_partitions
|
47
40
|
end
|
48
41
|
|
49
|
-
groupings.
|
42
|
+
groupings.each do |key, messages_group|
|
43
|
+
yield(key, messages_group)
|
44
|
+
end
|
50
45
|
else
|
51
46
|
# When no virtual partitioner, works as regular one
|
52
47
|
yield(0, messages)
|
data/lib/karafka/process.rb
CHANGED
@@ -29,12 +29,19 @@ module Karafka
|
|
29
29
|
# Creates an instance of process and creates empty hash for callbacks
|
30
30
|
def initialize
|
31
31
|
@callbacks = Hash.new { |hsh, key| hsh[key] = [] }
|
32
|
+
@supervised = false
|
32
33
|
end
|
33
34
|
|
34
35
|
# Method catches all HANDLED_SIGNALS and performs appropriate callbacks (if defined)
|
35
36
|
# @note If there are no callbacks, this method will just ignore a given signal that was sent
|
36
37
|
def supervise
|
37
38
|
HANDLED_SIGNALS.each { |signal| trap_signal(signal) }
|
39
|
+
@supervised = true
|
40
|
+
end
|
41
|
+
|
42
|
+
# Is the current process supervised and are trap signals installed
|
43
|
+
def supervised?
|
44
|
+
@supervised
|
38
45
|
end
|
39
46
|
|
40
47
|
private
|
data/lib/karafka/server.rb
CHANGED
@@ -31,6 +31,7 @@ module Karafka
|
|
31
31
|
process.on_sigint { Thread.new { stop } }
|
32
32
|
process.on_sigquit { Thread.new { stop } }
|
33
33
|
process.on_sigterm { Thread.new { stop } }
|
34
|
+
process.supervise
|
34
35
|
|
35
36
|
# Start is blocking until stop is called and when we stop, it will wait until
|
36
37
|
# all of the things are ready to stop
|
@@ -61,7 +62,6 @@ module Karafka
|
|
61
62
|
# @note We don't need to sleep because Karafka::Fetcher is locking and waiting to
|
62
63
|
# finish loop (and it won't happen until we explicitly want to stop)
|
63
64
|
def start
|
64
|
-
process.supervise
|
65
65
|
Karafka::App.run!
|
66
66
|
Karafka::Runner.new.call
|
67
67
|
end
|
@@ -73,6 +73,9 @@ module Karafka
|
|
73
73
|
# lock them forever. If you need to run Karafka shutdown from within workers threads,
|
74
74
|
# please start a separate thread to do so.
|
75
75
|
def stop
|
76
|
+
# Initialize the stopping process only if Karafka was running
|
77
|
+
return unless Karafka::App.running?
|
78
|
+
|
76
79
|
Karafka::App.stop!
|
77
80
|
|
78
81
|
timeout = Karafka::App.config.shutdown_timeout
|
@@ -110,8 +113,12 @@ module Karafka
|
|
110
113
|
|
111
114
|
Karafka::App.producer.close
|
112
115
|
|
116
|
+
# We also do not forcefully terminate everything when running in the embedded mode,
|
117
|
+
# otherwise we would overwrite the shutdown process of the process that started Karafka
|
118
|
+
return unless process.supervised?
|
119
|
+
|
113
120
|
# exit! is not within the instrumentation as it would not trigger due to exit
|
114
|
-
Kernel.exit!
|
121
|
+
Kernel.exit!(FORCEFUL_EXIT_CODE)
|
115
122
|
ensure
|
116
123
|
Karafka::App.stopped!
|
117
124
|
end
|
data/lib/karafka/status.rb
CHANGED
@@ -3,6 +3,12 @@
|
|
3
3
|
module Karafka
|
4
4
|
module TimeTrackers
|
5
5
|
# Handles Kafka topic partition pausing and resuming with exponential back-offs.
|
6
|
+
# Since expiring and pausing can happen from both consumer and listener, this needs to be
|
7
|
+
# thread-safe.
|
8
|
+
#
|
9
|
+
# @note We do not have to worry about performance implications of a mutex wrapping most of the
|
10
|
+
# code here, as this is not a frequently used tracker. It is active only once per batch in
|
11
|
+
# case of long-running-jobs and upon errors.
|
6
12
|
class Pause < Base
|
7
13
|
attr_reader :count
|
8
14
|
|
@@ -36,6 +42,7 @@ module Karafka
|
|
36
42
|
@timeout = timeout
|
37
43
|
@max_timeout = max_timeout
|
38
44
|
@exponential_backoff = exponential_backoff
|
45
|
+
@mutex = Mutex.new
|
39
46
|
super()
|
40
47
|
end
|
41
48
|
|
@@ -45,35 +52,47 @@ module Karafka
|
|
45
52
|
# @note Providing this value can be useful when we explicitly want to pause for a certain
|
46
53
|
# period of time, outside of any regular pausing logic
|
47
54
|
def pause(timeout = backoff_interval)
|
48
|
-
@
|
49
|
-
|
50
|
-
|
55
|
+
@mutex.synchronize do
|
56
|
+
@started_at = now
|
57
|
+
@ends_at = @started_at + timeout
|
58
|
+
@count += 1
|
59
|
+
end
|
51
60
|
end
|
52
61
|
|
53
62
|
# Marks the pause as resumed.
|
54
63
|
def resume
|
55
|
-
@
|
56
|
-
|
64
|
+
@mutex.synchronize do
|
65
|
+
@started_at = nil
|
66
|
+
@ends_at = nil
|
67
|
+
end
|
57
68
|
end
|
58
69
|
|
59
70
|
# Expires the pause, so it can be considered expired
|
60
71
|
def expire
|
61
|
-
@
|
72
|
+
@mutex.synchronize do
|
73
|
+
@ends_at = nil
|
74
|
+
end
|
62
75
|
end
|
63
76
|
|
64
77
|
# @return [Boolean] are we paused from processing
|
65
78
|
def paused?
|
66
|
-
|
79
|
+
@mutex.synchronize do
|
80
|
+
!@started_at.nil?
|
81
|
+
end
|
67
82
|
end
|
68
83
|
|
69
84
|
# @return [Boolean] did the pause expire
|
70
85
|
def expired?
|
71
|
-
@
|
86
|
+
@mutex.synchronize do
|
87
|
+
@ends_at ? now >= @ends_at : true
|
88
|
+
end
|
72
89
|
end
|
73
90
|
|
74
91
|
# Resets the pause counter.
|
75
92
|
def reset
|
76
|
-
@
|
93
|
+
@mutex.synchronize do
|
94
|
+
@count = 0
|
95
|
+
end
|
77
96
|
end
|
78
97
|
|
79
98
|
private
|
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
module Karafka
|
4
4
|
module TimeTrackers
|
5
|
-
# Object used to keep track of time we've used running certain operations.
|
5
|
+
# Object used to keep track of time we've used running certain operations. Polling is
|
6
|
+
# running in a single thread, thus we do not have to worry about this being thread-safe.
|
6
7
|
#
|
7
8
|
# @example Keep track of sleeping and stop after 3 seconds of 0.1 sleep intervals
|
8
9
|
# time_poll = Poll.new(3000)
|
data/lib/karafka/version.rb
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: karafka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Mensfeld
|
@@ -35,7 +35,7 @@ cert_chain:
|
|
35
35
|
Qf04B9ceLUaC4fPVEz10FyobjaFoY4i32xRto3XnrzeAgfEe4swLq8bQsR3w/EF3
|
36
36
|
MGU0FeSV2Yj7Xc2x/7BzLK8xQn5l7Yy75iPF+KP3vVmDHnNl
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2022-10-
|
38
|
+
date: 2022-10-20 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
41
|
name: karafka-core
|
@@ -188,6 +188,7 @@ files:
|
|
188
188
|
- lib/karafka/contracts/consumer_group.rb
|
189
189
|
- lib/karafka/contracts/consumer_group_topic.rb
|
190
190
|
- lib/karafka/contracts/server_cli_options.rb
|
191
|
+
- lib/karafka/embedded.rb
|
191
192
|
- lib/karafka/env.rb
|
192
193
|
- lib/karafka/errors.rb
|
193
194
|
- lib/karafka/helpers/async.rb
|
metadata.gz.sig
CHANGED
Binary file
|