sidekiq-benchmark 0.4.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +1 -2
- data/Makefile +26 -0
- data/README.md +1 -4
- data/docker-compose.yml +35 -0
- data/lib/sidekiq-benchmark.rb +5 -0
- data/lib/sidekiq-benchmark/version.rb +1 -1
- data/lib/sidekiq-benchmark/web.rb +34 -21
- data/lib/sidekiq-benchmark/worker.rb +29 -19
- data/sidekiq-benchmark.gemspec +3 -4
- data/test/lib/testing.rb +5 -4
- data/test/lib/web_test.rb +20 -15
- data/test/lib/worker_test.rb +17 -19
- data/test/test_helper.rb +4 -2
- data/web/assets/javascripts/chartkick.js +2239 -322
- data/web/views/benchmarks.erb +27 -5
- metadata +36 -49
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9ff40d5ce3fb48bd55615763f3e3ac80512aa698f55b654f6c42bb028ee573e0
|
4
|
+
data.tar.gz: b430cac0a57e74485caaac5e9c726f2fb17de9f5637c3febd3f9925258da3c2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f651f4b5349baea57d53f747a2813e349004521e628e82615a14f228b8ae5b5991e7d4603f1e0487068b02cfa44c89d2487402a848ffd590e0abc93c60f5b78
|
7
|
+
data.tar.gz: 985cc8dff35334d70e23121185fe7adc390145fdc237e9adccf423e9614f0a2e0e5616ed9cee94d55867ff4ff4ef88d95b100843291bb7307335c5488a7ea234
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/Makefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
.PHONY: test
|
2
|
+
|
3
|
+
DOCKER_CONSOLE := docker-compose run -w /app --rm console
|
4
|
+
PROJECT_NAME ?= $(shell basename $(shell pwd))
|
5
|
+
|
6
|
+
container:
|
7
|
+
mkdir -p gem/
|
8
|
+
mkdir -p vendor/
|
9
|
+
docker-compose build
|
10
|
+
$(DOCKER_CONSOLE) bundle install
|
11
|
+
|
12
|
+
bundle bundle_install bundle_update:
|
13
|
+
$(eval bundle_cmd ?= $(shell echo $@ | tr _ ' '))
|
14
|
+
$(DOCKER_CONSOLE) $(bundle_cmd)
|
15
|
+
|
16
|
+
build:
|
17
|
+
$(DOCKER_CONSOLE) gem build $(PROJECT_NAME).gemspec
|
18
|
+
|
19
|
+
clean:
|
20
|
+
$(DOCKER_CONSOLE) rm -fr gem/
|
21
|
+
|
22
|
+
test:
|
23
|
+
$(DOCKER_CONSOLE) bundle exec rake test
|
24
|
+
|
25
|
+
console:
|
26
|
+
$(DOCKER_CONSOLE)
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ And then execute:
|
|
19
19
|
|
20
20
|
## Requirements
|
21
21
|
|
22
|
-
|
22
|
+
From version 0.5.0 works with Sidekiq 4.2 or newer
|
23
23
|
|
24
24
|
## Usage
|
25
25
|
|
@@ -92,6 +92,3 @@ require 'sidekiq-benchmark/testing'
|
|
92
92
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
93
93
|
4. Push to the branch (`git push origin my-new-feature`)
|
94
94
|
5. Create new Pull Request
|
95
|
-
|
96
|
-
|
97
|
-
[![endorse](https://api.coderwall.com/kosmatov/endorsecount.png)](https://coderwall.com/kosmatov)
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
version: '3.8'
|
2
|
+
|
3
|
+
x-logging: &logging
|
4
|
+
options:
|
5
|
+
max-size: '5k'
|
6
|
+
max-file: '5'
|
7
|
+
labels: "{{.Name}}"
|
8
|
+
driver: json-file
|
9
|
+
|
10
|
+
services:
|
11
|
+
app: &base
|
12
|
+
image: ruby:latest
|
13
|
+
environment: &app_env
|
14
|
+
- BUNDLE_PATH=/app/vendor
|
15
|
+
- REDIS_HOST=redis
|
16
|
+
volumes:
|
17
|
+
- .:/app:cached
|
18
|
+
- ./vendor:/app/vendor
|
19
|
+
- ./gem:/app/gem
|
20
|
+
- ~/.pry_history:/root/.pry_history
|
21
|
+
- ~/.bash_history:/root/.bash_history
|
22
|
+
links:
|
23
|
+
- redis:redis
|
24
|
+
logging: *logging
|
25
|
+
|
26
|
+
redis:
|
27
|
+
image: redis:alpine
|
28
|
+
logging: *logging
|
29
|
+
|
30
|
+
console:
|
31
|
+
<<: *base
|
32
|
+
command: bash
|
33
|
+
|
34
|
+
volumes:
|
35
|
+
vendor_cache:
|
data/lib/sidekiq-benchmark.rb
CHANGED
@@ -6,6 +6,11 @@ Sidekiq::Web.tabs["Benchmarks"] = "benchmarks"
|
|
6
6
|
|
7
7
|
module Sidekiq
|
8
8
|
module Benchmark
|
9
|
+
REDIS_NAMESPACE = :benchmark
|
10
|
+
TYPES_KEY = "#{REDIS_NAMESPACE}:types".freeze
|
11
|
+
STAT_KEYS = %i[stats total]
|
12
|
+
REDIS_KEYS_TTL = 3600 * 24 * 30
|
13
|
+
|
9
14
|
autoload :Worker, 'sidekiq-benchmark/worker'
|
10
15
|
end
|
11
16
|
end
|
@@ -1,41 +1,43 @@
|
|
1
|
-
require 'sinatra/assetpack'
|
2
1
|
require 'chartkick'
|
3
2
|
|
4
3
|
module Sidekiq
|
5
4
|
module Benchmark
|
6
5
|
module Web
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
WEB_DIR = File.expand_path("../../../web", __FILE__).freeze
|
7
|
+
JS_DIR = File.join(WEB_DIR, "assets", "javascripts").freeze
|
8
|
+
VIEW_PATH = File.join(WEB_DIR, "views", "benchmarks.erb").freeze
|
10
9
|
|
10
|
+
def self.registered(app)
|
11
11
|
app.helpers Chartkick::Helper
|
12
|
-
app.register Sinatra::AssetPack
|
13
|
-
|
14
|
-
app.assets {
|
15
|
-
serve '/js', from: js_dir
|
16
12
|
|
17
|
-
|
18
|
-
|
13
|
+
app.get '/benchmarks/javascripts/chartkick.js' do
|
14
|
+
body = File.read File.join(JS_DIR, 'chartkick.js')
|
15
|
+
headers = {
|
16
|
+
'Content-Type' => 'application/javascript',
|
17
|
+
'Cache-Control' => 'public, max-age=84600'
|
18
|
+
}
|
19
|
+
[200, headers, [body]]
|
20
|
+
end
|
19
21
|
|
20
22
|
app.get "/benchmarks" do
|
21
23
|
@charts = {}
|
22
24
|
|
23
25
|
Sidekiq.redis do |conn|
|
24
|
-
@types = conn.smembers
|
26
|
+
@types = conn.smembers TYPES_KEY
|
25
27
|
@types.each do |type|
|
26
|
-
@charts[type] = {
|
28
|
+
@charts[type] = STAT_KEYS.reduce({}) { |a, e| a[e] = []; a }
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
+
total_key = "#{REDIS_NAMESPACE}:#{type}:total"
|
31
|
+
total_keys = conn.hkeys(total_key) - %w(start_time job_time finish_time)
|
30
32
|
|
31
|
-
total_time = conn.hget
|
33
|
+
total_time = conn.hget total_key, :job_time
|
32
34
|
total_time = total_time.to_f
|
33
35
|
total_keys.each do |key|
|
34
|
-
value = conn.hget
|
36
|
+
value = conn.hget total_key, key
|
35
37
|
@charts[type][:total] << [key, value.to_f.round(2)]
|
36
38
|
end
|
37
39
|
|
38
|
-
stats = conn.hgetall "
|
40
|
+
stats = conn.hgetall "#{REDIS_NAMESPACE}:#{type}:stats"
|
39
41
|
stats.each do |key, value|
|
40
42
|
@charts[type][:stats] << [key.to_f, value.to_i]
|
41
43
|
end
|
@@ -45,14 +47,25 @@ module Sidekiq
|
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
|
49
|
-
template = File.read view_path
|
50
|
-
render :erb, template
|
50
|
+
erb File.read(VIEW_PATH)
|
51
51
|
end
|
52
52
|
|
53
53
|
app.post "/benchmarks/remove" do
|
54
54
|
Sidekiq.redis do |conn|
|
55
|
-
keys =
|
55
|
+
keys = STAT_KEYS.map { |key| "#{REDIS_NAMESPACE}:#{params[:type]}:#{key}" }
|
56
|
+
conn.srem TYPES_KEY, params[:type]
|
57
|
+
conn.del keys
|
58
|
+
end
|
59
|
+
|
60
|
+
redirect "#{root_path}benchmarks"
|
61
|
+
end
|
62
|
+
app.post "/benchmarks/remove_all" do
|
63
|
+
Sidekiq.redis do |conn|
|
64
|
+
types = conn.smembers TYPES_KEY
|
65
|
+
keys = STAT_KEYS.map do |key|
|
66
|
+
types.map { |type| "#{REDIS_NAMESPACE}:#{type}:#{key}" }
|
67
|
+
end.flatten
|
68
|
+
keys << TYPES_KEY
|
56
69
|
conn.del keys
|
57
70
|
end
|
58
71
|
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sidekiq
|
2
4
|
module Benchmark
|
3
5
|
module Worker
|
4
|
-
|
5
6
|
def benchmark(options = {})
|
6
7
|
@benchmark ||= Benchmark.new self, benchmark_redis_type_key, options
|
7
8
|
|
@@ -18,9 +19,7 @@ module Sidekiq
|
|
18
19
|
end
|
19
20
|
|
20
21
|
class Benchmark
|
21
|
-
|
22
|
-
|
23
|
-
attr_reader :metrics, :start_time, :finish_time, :redis_key
|
22
|
+
attr_reader :metrics, :start_time, :finish_time, :redis_keys
|
24
23
|
|
25
24
|
def initialize(worker, redis_key, options)
|
26
25
|
@metrics = {}
|
@@ -28,7 +27,12 @@ module Sidekiq
|
|
28
27
|
@options = options
|
29
28
|
@start_time = Time.now
|
30
29
|
|
31
|
-
@
|
30
|
+
@redis_keys =
|
31
|
+
%i[total stats].reduce({}) do |m, e|
|
32
|
+
m[e] = "#{REDIS_NAMESPACE}:#{redis_key}:#{e}"
|
33
|
+
m
|
34
|
+
end
|
35
|
+
|
32
36
|
set_redis_key redis_key
|
33
37
|
end
|
34
38
|
|
@@ -46,6 +50,8 @@ module Sidekiq
|
|
46
50
|
self[name] ||= 0.0
|
47
51
|
self[name] += t1 - t0
|
48
52
|
|
53
|
+
Sidekiq.logger.info "Benchmark #{name}: #{t1 - t0} sec." if @options[:log]
|
54
|
+
|
49
55
|
ret
|
50
56
|
end
|
51
57
|
alias_method :bm, :measure
|
@@ -62,18 +68,10 @@ module Sidekiq
|
|
62
68
|
@metrics[name]
|
63
69
|
end
|
64
70
|
|
65
|
-
def method_missing(name, *args, &block)
|
66
|
-
if block_given?
|
67
|
-
measure(name, &block)
|
68
|
-
self[name]
|
69
|
-
else
|
70
|
-
self[name] = args[0]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
71
|
def set_redis_key(key)
|
75
72
|
Sidekiq.redis do |conn|
|
76
|
-
conn.sadd
|
73
|
+
conn.sadd TYPES_KEY, key
|
74
|
+
conn.expire TYPES_KEY, REDIS_KEYS_TTL
|
77
75
|
end
|
78
76
|
end
|
79
77
|
|
@@ -83,17 +81,29 @@ module Sidekiq
|
|
83
81
|
Sidekiq.redis do |conn|
|
84
82
|
conn.multi do
|
85
83
|
@metrics.each do |key, value|
|
86
|
-
conn.hincrbyfloat
|
84
|
+
conn.hincrbyfloat redis_keys[:total], key, value
|
87
85
|
end
|
88
86
|
|
89
|
-
conn.hincrby
|
87
|
+
conn.hincrby redis_keys[:stats], job_time_key, 1
|
88
|
+
|
89
|
+
conn.hsetnx redis_keys[:total], "start_time", start_time
|
90
|
+
conn.hset redis_keys[:total], "finish_time", finish_time
|
90
91
|
|
91
|
-
conn.
|
92
|
-
conn.
|
92
|
+
conn.expire redis_keys[:stats], REDIS_KEYS_TTL
|
93
|
+
conn.expire redis_keys[:total], REDIS_KEYS_TTL
|
93
94
|
end
|
94
95
|
end
|
95
96
|
end
|
96
97
|
|
98
|
+
def method_missing(name, *args, &block)
|
99
|
+
if block_given?
|
100
|
+
measure(name, &block)
|
101
|
+
self[name]
|
102
|
+
else
|
103
|
+
self[name] = args[0]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
97
107
|
end
|
98
108
|
end
|
99
109
|
end
|
data/sidekiq-benchmark.gemspec
CHANGED
@@ -18,14 +18,13 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.add_dependency "chartkick",
|
22
|
-
gem.add_dependency "
|
21
|
+
gem.add_dependency "chartkick", ">= 1.1.1"
|
22
|
+
gem.add_dependency "sidekiq", "~> 5"
|
23
23
|
|
24
|
-
gem.add_development_dependency "sidekiq"
|
25
|
-
gem.add_development_dependency "sinatra"
|
26
24
|
gem.add_development_dependency "rake"
|
27
25
|
gem.add_development_dependency "rack-test"
|
28
26
|
gem.add_development_dependency "minitest", "~> 5"
|
29
27
|
gem.add_development_dependency "coveralls"
|
28
|
+
gem.add_development_dependency "pry"
|
30
29
|
gem.add_development_dependency 'delorean', '~> 2.1'
|
31
30
|
end
|
data/test/lib/testing.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'sidekiq-benchmark/testing'
|
3
2
|
|
4
3
|
class Sidekiq::Benchmark::TestingTest < Minitest::Spec
|
4
|
+
require 'sidekiq-benchmark/testing'
|
5
|
+
|
5
6
|
describe 'Testing' do
|
6
7
|
before do
|
7
8
|
Sidekiq::Benchmark::Test.flush_db
|
@@ -10,13 +11,13 @@ class Sidekiq::Benchmark::TestingTest < Minitest::Spec
|
|
10
11
|
|
11
12
|
it "save nothing to redis" do
|
12
13
|
Sidekiq.redis do |conn|
|
13
|
-
total_time = conn.hget(
|
14
|
-
total_time.must_be_nil
|
14
|
+
total_time = conn.hget(@worker.benchmark.redis_keys[:total], :job_time)
|
15
|
+
_(total_time).must_be_nil
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
19
|
it "run code in bm blocks" do
|
19
|
-
@worker.counter.wont_equal 0
|
20
|
+
_(@worker.counter).wont_equal 0
|
20
21
|
end
|
21
22
|
end
|
22
23
|
end
|
data/test/lib/web_test.rb
CHANGED
@@ -14,33 +14,38 @@ module Sidekiq
|
|
14
14
|
Test.flush_db
|
15
15
|
end
|
16
16
|
|
17
|
-
it "
|
17
|
+
it "display index without stats" do
|
18
18
|
get '/benchmarks'
|
19
|
-
last_response.status.must_equal 200
|
19
|
+
_(last_response.status).must_equal 200
|
20
20
|
end
|
21
21
|
|
22
|
-
it "
|
22
|
+
it "display index with stats" do
|
23
23
|
WorkerMock.new
|
24
24
|
|
25
25
|
get '/benchmarks'
|
26
|
-
last_response.status.must_equal 200
|
26
|
+
_(last_response.status).must_equal 200
|
27
27
|
end
|
28
28
|
|
29
|
-
it "
|
29
|
+
it "remove all benchmarks data" do
|
30
30
|
WorkerMock.new
|
31
31
|
|
32
|
-
Sidekiq.redis
|
33
|
-
keys = conn.keys "benchmark:*"
|
34
|
-
keys.wont_be_empty
|
35
|
-
end
|
32
|
+
Sidekiq.redis { |conn| _(conn.keys("benchmark:*")).wont_be_empty }
|
36
33
|
|
37
|
-
post '/benchmarks/
|
38
|
-
last_response.status.must_equal 302
|
34
|
+
post '/benchmarks/remove_all'
|
35
|
+
_(last_response.status).must_equal 302
|
39
36
|
|
40
|
-
Sidekiq.redis
|
41
|
-
|
42
|
-
|
43
|
-
|
37
|
+
Sidekiq.redis { |conn| _(conn.keys("benchmark:*")).must_be_empty }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "remove benchmark data" do
|
41
|
+
WorkerMock.new
|
42
|
+
|
43
|
+
Sidekiq.redis { |conn| _(conn.keys("benchmark:sidekiq_benchmark_test_workermock:*")).wont_be_empty }
|
44
|
+
|
45
|
+
post '/benchmarks/remove', type: :sidekiq_benchmark_test_workermock
|
46
|
+
_(last_response.status).must_equal 302
|
47
|
+
|
48
|
+
Sidekiq.redis { |conn| _(conn.keys("benchmark:sidekiq_benchmark_test_workermock:*")).must_be_empty }
|
44
49
|
end
|
45
50
|
end
|
46
51
|
end
|
data/test/lib/worker_test.rb
CHANGED
@@ -16,12 +16,12 @@ module Sidekiq
|
|
16
16
|
metrics = @worker.benchmark.metrics
|
17
17
|
|
18
18
|
@worker.metric_names.each do |metric_name|
|
19
|
-
metrics[metric_name].wont_be_nil
|
19
|
+
_(metrics[metric_name]).wont_be_nil
|
20
20
|
end
|
21
21
|
|
22
|
-
@worker.benchmark.start_time.wont_be_nil
|
23
|
-
@worker.benchmark.finish_time.wont_be_nil
|
24
|
-
metrics[:assigned_metric].must_equal @worker.assigned_metric
|
22
|
+
_(@worker.benchmark.start_time).wont_be_nil
|
23
|
+
_(@worker.benchmark.finish_time).wont_be_nil
|
24
|
+
_(metrics[:assigned_metric]).must_equal @worker.assigned_metric
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'should add up metrics' do
|
@@ -33,11 +33,11 @@ module Sidekiq
|
|
33
33
|
|
34
34
|
it "should save metrics to redis" do
|
35
35
|
Sidekiq.redis do |conn|
|
36
|
-
total_time = conn.hget(
|
37
|
-
total_time.wont_be_nil
|
36
|
+
total_time = conn.hget(@worker.benchmark.redis_keys[:total], :job_time)
|
37
|
+
_(total_time).wont_be_nil
|
38
38
|
|
39
|
-
metrics = conn.hkeys(
|
40
|
-
metrics.wont_be_empty
|
39
|
+
metrics = conn.hkeys(@worker.benchmark.redis_keys[:stats])
|
40
|
+
_(metrics).wont_be_empty
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
@@ -46,23 +46,21 @@ module Sidekiq
|
|
46
46
|
metrics = worker.benchmark.metrics
|
47
47
|
|
48
48
|
Sidekiq.redis do |conn|
|
49
|
-
metric_set = conn.hkeys(
|
50
|
-
metric_set.must_be_empty
|
49
|
+
metric_set = conn.hkeys(worker.benchmark.redis_keys[:stats])
|
50
|
+
_(metric_set).must_be_empty
|
51
51
|
end
|
52
52
|
|
53
53
|
worker.metric_names.each do |metric_name|
|
54
|
-
metrics[metric_name].wont_be_nil
|
54
|
+
_(metrics[metric_name]).wont_be_nil
|
55
55
|
end
|
56
56
|
|
57
|
-
worker.benchmark.finish_time.must_be_nil
|
58
|
-
|
57
|
+
_(worker.benchmark.finish_time).must_be_nil
|
59
58
|
worker.finish
|
60
|
-
|
61
|
-
worker.benchmark.finish_time.wont_be_nil
|
59
|
+
_(worker.benchmark.finish_time).wont_be_nil
|
62
60
|
|
63
61
|
Sidekiq.redis do |conn|
|
64
|
-
metric_set = conn.hkeys(
|
65
|
-
metric_set.wont_be_empty
|
62
|
+
metric_set = conn.hkeys(worker.benchmark.redis_keys[:stats])
|
63
|
+
_(metric_set).wont_be_empty
|
66
64
|
end
|
67
65
|
end
|
68
66
|
|
@@ -70,8 +68,8 @@ module Sidekiq
|
|
70
68
|
worker = AlterWorkerMock.new
|
71
69
|
value = worker.benchmark.call(:multiply, 4, 4)
|
72
70
|
|
73
|
-
value.must_equal 16
|
74
|
-
worker.benchmark.metrics[:multiply].wont_be_nil
|
71
|
+
_(value).must_equal 16
|
72
|
+
_(worker.benchmark.metrics[:multiply]).wont_be_nil
|
75
73
|
end
|
76
74
|
|
77
75
|
end
|