sidekiq-status 3.0.0 → 3.0.2
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
- data/CHANGELOG.md +6 -0
- data/README.md +9 -4
- data/lib/sidekiq-status/server_middleware.rb +20 -18
- data/lib/sidekiq-status/version.rb +1 -1
- data/lib/sidekiq-status/web.rb +18 -1
- data/lib/sidekiq-status/worker.rb +7 -2
- data/lib/sidekiq-status.rb +15 -0
- data/spec/lib/sidekiq-status/server_middleware_spec.rb +16 -0
- data/spec/lib/sidekiq-status/worker_spec.rb +18 -0
- data/spec/support/test_jobs.rb +12 -0
- data/web/views/status.erb +26 -0
- data/web/views/statuses.erb +10 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7c2c40656501ca39c5bc87ec1b1a81acc8f8f24fcde74dfe13b60a3659ae67fb
|
4
|
+
data.tar.gz: 1647fe3d39f47444615bf83e6ba31d69ad750fdab07c23a7cafeb85f15991b93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29f7ba740739147cf2a3f3050d89ed89403d83c39e1c23d31246e4c5a0f73883a1cf7146c5b11d378673a057ab6629c76fd666c9436c5f14b4ef292e0765a0ff
|
7
|
+
data.tar.gz: c71ff262e667f0c1f330dbcf0ab51783cef4d7a5fe37a7406465d3f6a8df51b1989040b817fd2c3f671c63cb0ea670eeb46240e9c4b6b0ab332544b779e75060
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
**Version 3.0.2**
|
2
|
+
- Avoids setting statuses for non-status jobs when an exception is thrown (https://github.com/kenaniah/sidekiq-status/pull/32)
|
3
|
+
|
4
|
+
**Version 3.0.1**
|
5
|
+
- Adds elapsed time and ETA to the job status page (https://github.com/kenaniah/sidekiq-status/pull/13)
|
6
|
+
|
1
7
|
**Version 3.0.0**
|
2
8
|
- Drops support for Sidekiq 5.x
|
3
9
|
- Adds support for Sidekiq 7.x
|
data/README.md
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# Sidekiq::Status
|
2
2
|
[](https://badge.fury.io/rb/sidekiq-status)
|
3
3
|
[](https://github.com/kenaniah/sidekiq-status/actions/)
|
4
|
-
[](https://inch-ci.org/github/kenaniah/sidekiq-status)
|
5
4
|
|
6
5
|
Sidekiq-status is an extension to [Sidekiq](https://github.com/mperham/sidekiq) that tracks information about your Sidekiq and provides a UI to that purpose. It was inspired by [resque-status](https://github.com/quirkey/resque-status).
|
7
6
|
|
@@ -21,6 +20,10 @@ Or install it yourself as:
|
|
21
20
|
gem install sidekiq-status
|
22
21
|
```
|
23
22
|
|
23
|
+
### Migrating to Version 3.x from 2.x
|
24
|
+
|
25
|
+
Version 3.0.0 adds support for Sidekiq 7.x, but drops support for Sidekiq 5.x. **You should be able to upgrade cleanly from version 2.x to 3.x provided you are running Sidekiq 6.x or newer.**
|
26
|
+
|
24
27
|
#### Migrating to Version 2.x from 1.x
|
25
28
|
|
26
29
|
Version 2.0.0 was published in order to add support for Ruby 3.0 and Sidekiq 6.x and to remove support for versions of both that are now end-of-life. **You should be able to upgrade cleanly from version 1.x to 2.x provided you are running Sidekiq 5.x or newer.**
|
@@ -46,15 +49,15 @@ require 'sidekiq-status'
|
|
46
49
|
|
47
50
|
Sidekiq.configure_client do |config|
|
48
51
|
# accepts :expiration (optional)
|
49
|
-
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes
|
52
|
+
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes.to_i
|
50
53
|
end
|
51
54
|
|
52
55
|
Sidekiq.configure_server do |config|
|
53
56
|
# accepts :expiration (optional)
|
54
|
-
Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes
|
57
|
+
Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes.to_i
|
55
58
|
|
56
59
|
# accepts :expiration (optional)
|
57
|
-
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes
|
60
|
+
Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes.to_i
|
58
61
|
end
|
59
62
|
```
|
60
63
|
|
@@ -175,6 +178,8 @@ Sidekiq::Status::at job_id #=> 5
|
|
175
178
|
Sidekiq::Status::total job_id #=> 100
|
176
179
|
Sidekiq::Status::message job_id #=> "Almost done"
|
177
180
|
Sidekiq::Status::pct_complete job_id #=> 5
|
181
|
+
Sidekiq::Status::working_at job_id #=> 2718
|
182
|
+
Sidekiq::Status::update_time job_id #=> 2819
|
178
183
|
```
|
179
184
|
|
180
185
|
### Unscheduling
|
@@ -43,26 +43,28 @@ module Sidekiq::Status
|
|
43
43
|
return
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
if
|
61
|
-
|
46
|
+
begin
|
47
|
+
# Determine job expiration
|
48
|
+
expiry = job_class.new.expiration || @expiration rescue @expiration
|
49
|
+
|
50
|
+
store_status worker.jid, :working, expiry
|
51
|
+
yield
|
52
|
+
store_status worker.jid, :complete, expiry
|
53
|
+
rescue Worker::Stopped
|
54
|
+
store_status worker.jid, :stopped, expiry
|
55
|
+
rescue SystemExit, Interrupt
|
56
|
+
store_status worker.jid, :interrupted, expiry
|
57
|
+
raise
|
58
|
+
rescue Exception
|
59
|
+
status = :failed
|
60
|
+
if msg['retry']
|
61
|
+
if retry_attempt_number(msg) < retry_attempts_from(msg['retry'], DEFAULT_MAX_RETRY_ATTEMPTS)
|
62
|
+
status = :retrying
|
63
|
+
end
|
62
64
|
end
|
65
|
+
store_status(worker.jid, status, expiry) if job_class && job_class.ancestors.include?(Sidekiq::Status::Worker)
|
66
|
+
raise
|
63
67
|
end
|
64
|
-
store_status(worker.jid, status, expiry) if job_class && job_class.ancestors.include?(Sidekiq::Status::Worker)
|
65
|
-
raise
|
66
68
|
end
|
67
69
|
|
68
70
|
private
|
data/lib/sidekiq-status/web.rb
CHANGED
@@ -8,7 +8,7 @@ module Sidekiq::Status
|
|
8
8
|
|
9
9
|
DEFAULT_PER_PAGE_OPTS = [25, 50, 100].freeze
|
10
10
|
DEFAULT_PER_PAGE = 25
|
11
|
-
COMMON_STATUS_HASH_KEYS = %w(update_time jid status worker args label pct_complete total at message)
|
11
|
+
COMMON_STATUS_HASH_KEYS = %w(update_time jid status worker args label pct_complete total at message working_at elapsed eta)
|
12
12
|
|
13
13
|
class << self
|
14
14
|
def per_page_opts= arr
|
@@ -48,6 +48,8 @@ module Sidekiq::Status
|
|
48
48
|
def add_details_to_status(status)
|
49
49
|
status['label'] = status_label(status['status'])
|
50
50
|
status["pct_complete"] ||= pct_complete(status)
|
51
|
+
status["elapsed"] ||= elapsed(status).to_s
|
52
|
+
status["eta"] ||= eta(status).to_s
|
51
53
|
status["custom"] = process_custom_data(status)
|
52
54
|
return status
|
53
55
|
end
|
@@ -61,6 +63,19 @@ module Sidekiq::Status
|
|
61
63
|
Sidekiq::Status::pct_complete(status['jid']) || 0
|
62
64
|
end
|
63
65
|
|
66
|
+
def elapsed(status)
|
67
|
+
case status['status']
|
68
|
+
when 'complete'
|
69
|
+
Sidekiq::Status.update_time(status['jid']) - Sidekiq::Status.working_at(status['jid'])
|
70
|
+
when 'working', 'retrying'
|
71
|
+
Time.now.to_i - Sidekiq::Status.working_at(status['jid'])
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def eta(status)
|
76
|
+
Sidekiq::Status.eta(status['jid']) if status['status'] == 'working'
|
77
|
+
end
|
78
|
+
|
64
79
|
def status_label(status)
|
65
80
|
case status
|
66
81
|
when 'complete'
|
@@ -122,6 +137,8 @@ module Sidekiq::Status
|
|
122
137
|
{id: "status", name: "Status", class: nil, url: nil},
|
123
138
|
{id: "update_time", name: "Last Updated", class: nil, url: nil},
|
124
139
|
{id: "pct_complete", name: "Progress", class: nil, url: nil},
|
140
|
+
{id: "elapsed", name: "Time Elapsed", class: nil, url: nil},
|
141
|
+
{id: "eta", name: "ETA", class: nil, url: nil},
|
125
142
|
]
|
126
143
|
|
127
144
|
@headers.each do |h|
|
@@ -29,7 +29,7 @@ module Sidekiq::Status::Worker
|
|
29
29
|
def at(num, message = nil)
|
30
30
|
@_status_total = 100 if @_status_total.nil?
|
31
31
|
pct_complete = ((num / @_status_total.to_f) * 100).to_i rescue 0
|
32
|
-
store(at: num, total: @_status_total, pct_complete: pct_complete, message: message)
|
32
|
+
store(at: num, total: @_status_total, pct_complete: pct_complete, message: message, working_at: working_at)
|
33
33
|
end
|
34
34
|
|
35
35
|
# Sets total number of tasks
|
@@ -37,7 +37,12 @@ module Sidekiq::Status::Worker
|
|
37
37
|
# @return [String]
|
38
38
|
def total(num)
|
39
39
|
@_status_total = num
|
40
|
-
store(total: num)
|
40
|
+
store(total: num, working_at: working_at)
|
41
41
|
end
|
42
42
|
|
43
|
+
private
|
44
|
+
|
45
|
+
def working_at
|
46
|
+
@working_at ||= Time.now.to_i
|
47
|
+
end
|
43
48
|
end
|
data/lib/sidekiq-status.rb
CHANGED
@@ -63,6 +63,21 @@ module Sidekiq::Status
|
|
63
63
|
get(job_id, :pct_complete).to_i
|
64
64
|
end
|
65
65
|
|
66
|
+
def working_at(job_id)
|
67
|
+
(get(job_id, :working_at) || Time.now).to_i
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_time(job_id)
|
71
|
+
(get(job_id, :update_time) || Time.now).to_i
|
72
|
+
end
|
73
|
+
|
74
|
+
def eta(job_id)
|
75
|
+
at = at(job_id)
|
76
|
+
return nil if at.zero?
|
77
|
+
|
78
|
+
(Time.now.to_i - working_at(job_id)).to_f / at * (total(job_id) - at)
|
79
|
+
end
|
80
|
+
|
66
81
|
def message(job_id)
|
67
82
|
get(job_id, :message)
|
68
83
|
end
|
@@ -61,6 +61,22 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
61
61
|
end
|
62
62
|
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil
|
63
63
|
end
|
64
|
+
|
65
|
+
it "should not set any status on system exit signal" do
|
66
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
67
|
+
start_server do
|
68
|
+
expect(ExitedNoStatusJob.perform_async).to eq(job_id)
|
69
|
+
end
|
70
|
+
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should not set any status on interrupt signal" do
|
74
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
75
|
+
start_server do
|
76
|
+
expect(InterruptedNoStatusJob.perform_async).to eq(job_id)
|
77
|
+
end
|
78
|
+
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil
|
79
|
+
end
|
64
80
|
end
|
65
81
|
|
66
82
|
context "sets interrupted status" do
|
@@ -20,4 +20,22 @@ describe Sidekiq::Status::Worker do
|
|
20
20
|
expect(subject.expiration).to eq(:val)
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
describe ".at" do
|
25
|
+
subject { StubJob.new }
|
26
|
+
|
27
|
+
it "records when the worker has started" do
|
28
|
+
expect { subject.at(0) }.to(change { subject.retrieve('working_at') })
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when setting the total for the worker" do
|
32
|
+
it "records when the worker has started" do
|
33
|
+
expect { subject.total(100) }.to(change { subject.retrieve('working_at') })
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it "records when the worker last worked" do
|
38
|
+
expect { subject.at(0) }.to(change { subject.retrieve('update_time') })
|
39
|
+
end
|
40
|
+
end
|
23
41
|
end
|
data/spec/support/test_jobs.rb
CHANGED
@@ -111,12 +111,24 @@ class ExitedJob < StubJob
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
+
class ExitedNoStatusJob < StubNoStatusJob
|
115
|
+
def perform
|
116
|
+
raise SystemExit
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
114
120
|
class InterruptedJob < StubJob
|
115
121
|
def perform
|
116
122
|
raise Interrupt
|
117
123
|
end
|
118
124
|
end
|
119
125
|
|
126
|
+
class InterruptedNoStatusJob < StubNoStatusJob
|
127
|
+
def perform
|
128
|
+
raise Interrupt
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
120
132
|
class RetriedJob < StubJob
|
121
133
|
|
122
134
|
sidekiq_options retry: true
|
data/web/views/status.erb
CHANGED
@@ -67,6 +67,32 @@
|
|
67
67
|
</div>
|
68
68
|
</div>
|
69
69
|
|
70
|
+
<div class="row">
|
71
|
+
<div class="col-sm-2">
|
72
|
+
<strong>Elapsed Time</strong>
|
73
|
+
</div>
|
74
|
+
<div class="col-sm-10">
|
75
|
+
<p>
|
76
|
+
<% if @status["elapsed"] %>
|
77
|
+
<%= ChronicDuration.output(@status["elapsed"].to_i, :weeks => true, :units => 2) %>
|
78
|
+
<% end %>
|
79
|
+
</p>
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
|
83
|
+
<div class="row">
|
84
|
+
<div class="col-sm-2">
|
85
|
+
<strong>ETA</strong>
|
86
|
+
</div>
|
87
|
+
<div class="col-sm-10">
|
88
|
+
<p>
|
89
|
+
<% if @status["eta"] %>
|
90
|
+
<%= ChronicDuration.output(@status["eta"].to_i, :weeks => true, :units => 2) %>
|
91
|
+
<% end %>
|
92
|
+
</p>
|
93
|
+
</div>
|
94
|
+
</div>
|
95
|
+
|
70
96
|
<% if @status["custom"].any? %>
|
71
97
|
<hr>
|
72
98
|
<% @status["custom"].each do |key, val| %>
|
data/web/views/statuses.erb
CHANGED
@@ -119,6 +119,16 @@ function setPerPage(select){
|
|
119
119
|
<% end %>
|
120
120
|
</div>
|
121
121
|
</td>
|
122
|
+
<td style='text-align: center; white-space: nowrap;'>
|
123
|
+
<% if container["elapsed"] %>
|
124
|
+
<%= ChronicDuration.output(container["elapsed"].to_i, :weeks => true, :units => 2) %>
|
125
|
+
<% end %>
|
126
|
+
</td>
|
127
|
+
<td style='text-align: center; white-space: nowrap;'>
|
128
|
+
<% if container["eta"] %>
|
129
|
+
<%= ChronicDuration.output(container["eta"].to_i, :weeks => true, :units => 2) %>
|
130
|
+
<% end %>
|
131
|
+
</td>
|
122
132
|
<td>
|
123
133
|
<div class="actions">
|
124
134
|
<form action="statuses" method="post">
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeniy Tsvigun
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-02
|
12
|
+
date: 2023-04-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sidekiq
|