sidekiq-status 1.1.0 → 2.0.0
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/.gitignore +1 -0
- data/.gitlab-ci.yml +17 -0
- data/.travis.yml +9 -6
- data/Appraisals +4 -8
- data/CHANGELOG.md +7 -57
- data/README.md +17 -24
- data/gemfiles/{sidekiq_3.x.gemfile → sidekiq_6.x.gemfile} +1 -1
- data/lib/sidekiq-status/server_middleware.rb +1 -1
- data/lib/sidekiq-status/storage.rb +1 -1
- data/lib/sidekiq-status/version.rb +1 -1
- data/lib/sidekiq-status/web.rb +24 -7
- data/sidekiq-status.gemspec +2 -2
- data/spec/lib/sidekiq-status/server_middleware_spec.rb +24 -6
- data/spec/lib/sidekiq-status/web_spec.rb +33 -0
- data/spec/lib/sidekiq-status_spec.rb +5 -5
- data/spec/support/test_jobs.rb +29 -0
- data/web/views/status.erb +18 -0
- data/web/views/statuses.erb +10 -1
- metadata +12 -13
- data/gemfiles/sidekiq_4.x.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8062f467160552b97566de033649c1b33869da92ce3ff168b1a20b1b38340eb6
|
4
|
+
data.tar.gz: 2a918b6cb05fe934db2521461b2abf26e4680def459486d4afe143e4a51d0cd6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d35f5ab165082045af4e53220d72a161a821816a3ec8f8cd8cec7ce2811358b9d78b56d211fea0cae65b5990e7fbbb04f4264e2a3f09588ce9c642cca3a705b
|
7
|
+
data.tar.gz: 558584271417c9eb89112268fd779c75f47e90044dd94c799675bec0a0f325a6015000e56a3d64397ed21eee0ae2089b22ad03bd73ed059b1ada368592e42e81
|
data/.gitignore
CHANGED
data/.gitlab-ci.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
dependency_scanning:
|
2
|
+
image: docker:stable
|
3
|
+
variables:
|
4
|
+
DOCKER_DRIVER: overlay2
|
5
|
+
allow_failure: true
|
6
|
+
services:
|
7
|
+
- docker:stable-dind
|
8
|
+
script:
|
9
|
+
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
|
10
|
+
- docker run
|
11
|
+
--env DEP_SCAN_DISABLE_REMOTE_CHECKS="${DEP_SCAN_DISABLE_REMOTE_CHECKS:-false}"
|
12
|
+
--volume "$PWD:/code"
|
13
|
+
--volume /var/run/docker.sock:/var/run/docker.sock
|
14
|
+
"registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$SP_VERSION" /code
|
15
|
+
artifacts:
|
16
|
+
reports:
|
17
|
+
dependency_scanning: gl-dependency-scanning-report.json
|
data/.travis.yml
CHANGED
@@ -1,16 +1,19 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.
|
4
|
-
- 2.
|
5
|
-
-
|
6
|
-
-
|
3
|
+
- 2.6
|
4
|
+
- 2.7
|
5
|
+
- 3.0
|
6
|
+
- ruby-head
|
7
7
|
gemfile:
|
8
|
-
- gemfiles/sidekiq_3.x.gemfile
|
9
|
-
- gemfiles/sidekiq_4.x.gemfile
|
10
8
|
- gemfiles/sidekiq_5.x.gemfile
|
9
|
+
- gemfiles/sidekiq_6.x.gemfile
|
11
10
|
before_install:
|
12
11
|
- gem update --system
|
13
12
|
- gem update bundler
|
14
13
|
services: redis
|
15
14
|
notifications:
|
16
15
|
email: false
|
16
|
+
matrix:
|
17
|
+
fast_finish: true
|
18
|
+
allow_failures:
|
19
|
+
- rvm: ruby-head
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,59 +1,9 @@
|
|
1
|
-
**Version
|
2
|
-
|
1
|
+
**Version 2.0.0**
|
2
|
+
* Adds support for Ruby 2.7, 3.0
|
3
|
+
* Adds support for Sidekiq 6.x
|
4
|
+
* Removes support for Ruby 2.3, 2.4, 2.5
|
5
|
+
* Removes support for Sidekiq 3.x, 4.x
|
3
6
|
|
4
|
-
**
|
5
|
-
+ Fixes status not being set to `:failed` after retries
|
7
|
+
**Versions 1.1.4 and prior**
|
6
8
|
|
7
|
-
|
8
|
-
+ Fixes namespacing in `sidekiq-status/testing/inline`
|
9
|
-
|
10
|
-
**Version 1.0.0**
|
11
|
-
+ Version number bumped to indicate stable release
|
12
|
-
|
13
|
-
**Version 0.8.1**
|
14
|
-
+ Avoids transient celluloid dependency in Sidekiq < 5.x
|
15
|
-
|
16
|
-
**Version 0.8.0**
|
17
|
-
+ Properly ignores jobs that do not have `Sidekiq::Status::Worker` included
|
18
|
-
+ Honors custom job expirations for ActiveJob jobs
|
19
|
-
+ Adds a `:retrying` status
|
20
|
-
+ Adds remove / retry buttons to the index page
|
21
|
-
+ Server middleware will now catches all exception types
|
22
|
-
+ Changes where server middleware is inserted in the chain
|
23
|
-
+ Reduces the amount of Redis calls made
|
24
|
-
+ Adds pagination / per page setting
|
25
|
-
+ Restores column sorting functionality
|
26
|
-
|
27
|
-
**Version 0.7.0**
|
28
|
-
+ Sidekiq 4.2 and 5 now supported
|
29
|
-
+ Added full support for ActiveJob
|
30
|
-
+ Updated Web UI
|
31
|
-
+ Styling updated to stay consistent with Sidekiq UI
|
32
|
-
+ Added header sorting
|
33
|
-
+ Fixed argument formatting
|
34
|
-
+ Times now display using natural language via ChronicDuration
|
35
|
-
+ Test suite fixed
|
36
|
-
|
37
|
-
**Version 0.6.0**
|
38
|
-
+ Updated Web UI
|
39
|
-
+ Will have all job statuses, previously it was showing only :working status
|
40
|
-
+ Bootstrap lables instead of badges for status
|
41
|
-
+ Added Arguments column to statuses page
|
42
|
-
+ New :interrupted status added
|
43
|
-
+ Added way to specify :expiration for Sidekiq::Status::ClientMiddleware
|
44
|
-
+ Bug fixes & Code cleaup
|
45
|
-
|
46
|
-
**Version 0.5.3**
|
47
|
-
+ some tweaks in web UI, separate redis namespace
|
48
|
-
|
49
|
-
**Version 0.5.2**
|
50
|
-
+ Sidekiq versions up to 3.3.* supported, jobs sorting options in web UI, more ruby versions
|
51
|
-
|
52
|
-
**Version 0.5.1**
|
53
|
-
+ dependencies versions requirements relaxed
|
54
|
-
|
55
|
-
**Version 0.5.0**
|
56
|
-
+ Sidekiq v3 support, redis pools support
|
57
|
-
|
58
|
-
**Version 0.4.0**
|
59
|
-
+ WebUI added, per-worker expiration setting enabled
|
9
|
+
See https://github.com/utgarda/sidekiq-status/blob/master/CHANGELOG.md.
|
data/README.md
CHANGED
@@ -1,16 +1,11 @@
|
|
1
1
|
# Sidekiq::Status
|
2
|
-
[](
|
3
|
-
[](https://gemnasium.com/utgarda/sidekiq-status)
|
6
|
-
[](http://inch-ci.org/github/utgarda/sidekiq-status)
|
2
|
+
[](https://badge.fury.io/rb/sidekiq-status)
|
3
|
+
[](https://www.travis-ci.com/github/kenaniah/sidekiq-status)
|
4
|
+
[](https://inch-ci.org/github/kenaniah/sidekiq-status)
|
7
5
|
|
8
|
-
|
9
|
-
by [resque-status](http://github.com/quirkey/resque-status) and mostly copying its features, using Sidekiq's middleware.
|
6
|
+
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).
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
Supports the latest versions of Sidekiq and all the way back to 3.x.
|
8
|
+
Requires Ruby 2.6+ and Sidekiq 5.0+ or newer.
|
14
9
|
|
15
10
|
## Installation
|
16
11
|
|
@@ -20,18 +15,18 @@ Add this line to your application's Gemfile:
|
|
20
15
|
gem 'sidekiq-status'
|
21
16
|
```
|
22
17
|
|
23
|
-
And then execute:
|
24
|
-
|
25
|
-
```bash
|
26
|
-
$ bundle
|
27
|
-
```
|
28
|
-
|
29
18
|
Or install it yourself as:
|
30
19
|
|
31
20
|
```bash
|
32
21
|
gem install sidekiq-status
|
33
22
|
```
|
34
23
|
|
24
|
+
### Migrating to Version 2.x from 1.x
|
25
|
+
|
26
|
+
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.
|
27
|
+
|
28
|
+
Sidekiq-status version 1.1.4 provides support all the way back to Sidekiq 3.x and was maintained at https://github.com/utgarda/sidekiq-status/.
|
29
|
+
|
35
30
|
## Setup Checklist
|
36
31
|
|
37
32
|
To get started:
|
@@ -63,9 +58,7 @@ Sidekiq.configure_server do |config|
|
|
63
58
|
end
|
64
59
|
```
|
65
60
|
|
66
|
-
|
67
|
-
|
68
|
-
After that you can use your jobs as usual. You need to also include the `Sidekiq::Status::Worker` module in your jobs if you want the additional functionality of tracking progress and storing / retrieving job data.
|
61
|
+
Include the `Sidekiq::Status::Worker` module in your jobs if you want the additional functionality of tracking progress and storing / retrieving job data.
|
69
62
|
|
70
63
|
``` ruby
|
71
64
|
class MyJob
|
@@ -78,7 +71,7 @@ class MyJob
|
|
78
71
|
end
|
79
72
|
```
|
80
73
|
|
81
|
-
|
74
|
+
Note: _only jobs that include `Sidekiq::Status::Worker`_ will have their statuses tracked.
|
82
75
|
|
83
76
|
To overwrite expiration on a per-worker basis, write an expiration method like the one below:
|
84
77
|
|
@@ -105,7 +98,7 @@ As sidekiq-status stores information about jobs in Redis, it is necessary to set
|
|
105
98
|
|
106
99
|
As explained above, the default expiration may also be overridden on a per-job basis by defining it within the job itself via a method called `#expiration`.
|
107
100
|
|
108
|
-
The expiration time set will be used as the [Redis expire time](
|
101
|
+
The expiration time set will be used as the [Redis expire time](https://redis.io/commands/expire), which is also known as the TTL (time to live). Once the expiration time has passed, all information about the job's status and any custom data stored via sidekiq-status will disappear.
|
109
102
|
|
110
103
|
It is advised that you set the expiration time greater than the amount of time required to complete the job.
|
111
104
|
|
@@ -131,7 +124,7 @@ Important: If you try any of the above status method after the expiration time,
|
|
131
124
|
|
132
125
|
### ActiveJob Support
|
133
126
|
|
134
|
-
|
127
|
+
This gem also supports ActiveJob jobs. Their status will be tracked automatically.
|
135
128
|
|
136
129
|
To also enable job progress tracking and data storage features, simply add the `Sidekiq::Status::Worker` module to your base class, like below:
|
137
130
|
|
@@ -216,11 +209,11 @@ This gem provides an extension to Sidekiq's web interface with an index at `/sta
|
|
216
209
|
|
217
210
|

|
218
211
|
|
219
|
-
|
212
|
+
Information for an individual job may be found at `/statuses/:job_id`.
|
220
213
|
|
221
214
|

|
222
215
|
|
223
|
-
|
216
|
+
Note: _only jobs that include `Sidekiq::Status::Worker`_ will be reported in the web interface.
|
224
217
|
|
225
218
|
#### Adding the Web Interface
|
226
219
|
|
@@ -90,7 +90,7 @@ module Sidekiq::Status::Storage
|
|
90
90
|
# - end: end score (i.e. +inf or a unix timestamp)
|
91
91
|
# - offset: current progress through (all) jobs (e.g.: 100 if you want jobs from 100 to BATCH_LIMIT)
|
92
92
|
def schedule_batch(options)
|
93
|
-
options[:conn].zrangebyscore "schedule", options[:start], options[:end],
|
93
|
+
options[:conn].zrangebyscore "schedule", options[:start], options[:end], limit: [options[:offset], BATCH_LIMIT]
|
94
94
|
end
|
95
95
|
|
96
96
|
# Searches the jobs Array for the job_id
|
data/lib/sidekiq-status/web.rb
CHANGED
@@ -8,6 +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
12
|
|
12
13
|
class << self
|
13
14
|
def per_page_opts= arr
|
@@ -47,9 +48,14 @@ module Sidekiq::Status
|
|
47
48
|
def add_details_to_status(status)
|
48
49
|
status['label'] = status_label(status['status'])
|
49
50
|
status["pct_complete"] ||= pct_complete(status)
|
51
|
+
status["custom"] = process_custom_data(status)
|
50
52
|
return status
|
51
53
|
end
|
52
54
|
|
55
|
+
def process_custom_data(hash)
|
56
|
+
hash.reject { |key, _| COMMON_STATUS_HASH_KEYS.include?(key) }
|
57
|
+
end
|
58
|
+
|
53
59
|
def pct_complete(status)
|
54
60
|
return 100 if status['status'] == 'complete'
|
55
61
|
Sidekiq::Status::pct_complete(status['jid']) || 0
|
@@ -75,8 +81,11 @@ module Sidekiq::Status
|
|
75
81
|
|
76
82
|
app.get '/statuses' do
|
77
83
|
|
78
|
-
|
79
|
-
|
84
|
+
jids = Sidekiq.redis do |conn|
|
85
|
+
conn.scan_each(match: 'sidekiq:status:*', count: 100).map do |key|
|
86
|
+
key.split(':').last
|
87
|
+
end.uniq
|
88
|
+
end
|
80
89
|
@statuses = []
|
81
90
|
|
82
91
|
jids.each do |jid|
|
@@ -96,6 +105,10 @@ module Sidekiq::Status
|
|
96
105
|
@statuses = @statuses.sort { |y,x| (x[sort_by] <=> y[sort_by]) || 1 }
|
97
106
|
end
|
98
107
|
|
108
|
+
if params[:status] && params[:status] != "all"
|
109
|
+
@statuses = @statuses.select {|job_status| job_status["status"] == params[:status] }
|
110
|
+
end
|
111
|
+
|
99
112
|
# Sidekiq pagination
|
100
113
|
@total_size = @statuses.count
|
101
114
|
@count = params[:per_page] ? params[:per_page].to_i : Sidekiq::Status::Web.default_per_page
|
@@ -123,7 +136,7 @@ module Sidekiq::Status
|
|
123
136
|
job = Sidekiq::Status::get_all params['jid']
|
124
137
|
|
125
138
|
if job.empty?
|
126
|
-
halt [404, {"Content-Type" => "text/html"}, [erb(sidekiq_status_template(:status_not_found))]]
|
139
|
+
throw :halt, [404, {"Content-Type" => "text/html"}, [erb(sidekiq_status_template(:status_not_found))]]
|
127
140
|
else
|
128
141
|
@status = add_details_to_status(job)
|
129
142
|
erb(sidekiq_status_template(:status))
|
@@ -135,21 +148,25 @@ module Sidekiq::Status
|
|
135
148
|
job = Sidekiq::RetrySet.new.find_job(params[:jid])
|
136
149
|
job ||= Sidekiq::DeadSet.new.find_job(params[:jid])
|
137
150
|
job.retry if job
|
138
|
-
halt [302, { "Location" => request.referer }, []]
|
151
|
+
throw :halt, [302, { "Location" => request.referer }, []]
|
139
152
|
end
|
140
153
|
|
141
154
|
# Removes a completed job from the status list
|
142
155
|
app.delete '/statuses' do
|
143
156
|
Sidekiq::Status.delete(params[:jid])
|
144
|
-
halt [302, { "Location" => request.referer }, []]
|
157
|
+
throw :halt, [302, { "Location" => request.referer }, []]
|
145
158
|
end
|
146
159
|
end
|
147
160
|
end
|
148
161
|
end
|
149
162
|
|
150
|
-
|
163
|
+
unless defined?(Sidekiq::Web)
|
164
|
+
require 'delegate' # Needed for sidekiq 5.x
|
165
|
+
require 'sidekiq/web'
|
166
|
+
end
|
167
|
+
|
151
168
|
Sidekiq::Web.register(Sidekiq::Status::Web)
|
152
|
-
["per_page", "sort_by", "sort_dir"].each do |key|
|
169
|
+
["per_page", "sort_by", "sort_dir", "status"].each do |key|
|
153
170
|
Sidekiq::WebHelpers::SAFE_QPARAMS.push(key)
|
154
171
|
end
|
155
172
|
if Sidekiq::Web.tabs.is_a?(Array)
|
data/sidekiq-status.gemspec
CHANGED
@@ -5,7 +5,7 @@ Gem::Specification.new do |gem|
|
|
5
5
|
gem.authors = ['Evgeniy Tsvigun', 'Kenaniah Cerny']
|
6
6
|
gem.email = ['utgarda@gmail.com', 'kenaniah@gmail.com']
|
7
7
|
gem.summary = 'An extension to the sidekiq message processing to track your jobs'
|
8
|
-
gem.homepage = 'http://github.com/
|
8
|
+
gem.homepage = 'http://github.com/kenaniah/sidekiq-status'
|
9
9
|
gem.license = 'MIT'
|
10
10
|
|
11
11
|
gem.files = `git ls-files`.split($\)
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
|
|
14
14
|
gem.require_paths = ['lib']
|
15
15
|
gem.version = Sidekiq::Status::VERSION
|
16
16
|
|
17
|
-
gem.add_dependency 'sidekiq', '>=
|
17
|
+
gem.add_dependency 'sidekiq', '>= 5.0'
|
18
18
|
gem.add_dependency 'chronic_duration'
|
19
19
|
gem.add_development_dependency 'appraisal'
|
20
20
|
gem.add_development_dependency 'colorize'
|
@@ -36,21 +36,39 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
36
36
|
it "sets failed status when Exception raised" do
|
37
37
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
38
38
|
start_server do
|
39
|
-
|
40
|
-
|
41
|
-
|
39
|
+
expect(capture_status_updates(3) {
|
40
|
+
expect(FailingHardJob.perform_async).to eq(job_id)
|
41
|
+
}).to eq([job_id]*3)
|
42
42
|
end
|
43
43
|
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('failed')
|
44
44
|
expect(Sidekiq::Status::failed?(job_id)).to be_truthy
|
45
45
|
end
|
46
46
|
|
47
|
+
context "when Sidekiq::Status::Worker is not included in the job" do
|
48
|
+
it "should not set a failed status" do
|
49
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
50
|
+
start_server do
|
51
|
+
expect(FailingNoStatusJob.perform_async).to eq(job_id)
|
52
|
+
end
|
53
|
+
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should not set any status when Exception raised" do
|
57
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
58
|
+
start_server do
|
59
|
+
expect(FailingHardNoStatusJob.perform_async).to eq(job_id)
|
60
|
+
end
|
61
|
+
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to be_nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
47
65
|
context "sets interrupted status" do
|
48
66
|
it "on system exit signal" do
|
49
67
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
50
68
|
start_server do
|
51
|
-
|
52
|
-
|
53
|
-
|
69
|
+
expect(capture_status_updates(3) {
|
70
|
+
expect(ExitedJob.perform_async).to eq(job_id)
|
71
|
+
}).to eq([job_id]*3)
|
54
72
|
end
|
55
73
|
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('interrupted')
|
56
74
|
expect(Sidekiq::Status::interrupted?(job_id)).to be_truthy
|
@@ -13,6 +13,7 @@ describe 'sidekiq status web' do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
before do
|
16
|
+
env 'rack.session', csrf: Base64.urlsafe_encode64('token')
|
16
17
|
client_middleware
|
17
18
|
allow(SecureRandom).to receive(:hex).and_return(job_id)
|
18
19
|
end
|
@@ -31,6 +32,27 @@ describe 'sidekiq status web' do
|
|
31
32
|
expect(last_response.body).to match(/working/)
|
32
33
|
end
|
33
34
|
|
35
|
+
it 'allows filtering the list of jobs by status' do
|
36
|
+
capture_status_updates(2) do
|
37
|
+
LongJob.perform_async(0.5)
|
38
|
+
end
|
39
|
+
|
40
|
+
get '/statuses?status=working'
|
41
|
+
expect(last_response).to be_ok
|
42
|
+
expect(last_response.body).to match(/#{job_id}/)
|
43
|
+
expect(last_response.body).to match(/LongJob/)
|
44
|
+
expect(last_response.body).to match(/working/)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'allows filtering the list of jobs by completed status' do
|
48
|
+
capture_status_updates(2) do
|
49
|
+
LongJob.perform_async(0.5)
|
50
|
+
end
|
51
|
+
get '/statuses?status=completed'
|
52
|
+
expect(last_response).to be_ok
|
53
|
+
expect(last_response.body).to_not match(/LongJob/)
|
54
|
+
end
|
55
|
+
|
34
56
|
it 'shows a single job in progress' do
|
35
57
|
capture_status_updates(2) do
|
36
58
|
LongJob.perform_async(1, 'another argument')
|
@@ -43,6 +65,17 @@ describe 'sidekiq status web' do
|
|
43
65
|
expect(last_response.body).to match(/working/)
|
44
66
|
end
|
45
67
|
|
68
|
+
it 'shows custom data for a single job' do
|
69
|
+
capture_status_updates(3) do
|
70
|
+
CustomDataJob.perform_async
|
71
|
+
end
|
72
|
+
|
73
|
+
get "/statuses/#{job_id}"
|
74
|
+
expect(last_response).to be_ok
|
75
|
+
expect(last_response.body).to match(/mister_cat/)
|
76
|
+
expect(last_response.body).to match(/meow/)
|
77
|
+
end
|
78
|
+
|
46
79
|
it 'show an error when the requested job ID is not found' do
|
47
80
|
get '/statuses/12345'
|
48
81
|
expect(last_response).to be_not_found
|
@@ -105,7 +105,7 @@ describe Sidekiq::Status do
|
|
105
105
|
second_job = LongJob.perform_in(3600)
|
106
106
|
expect(second_job).to eq(job_id_1)
|
107
107
|
|
108
|
-
initial_schedule = redis.zrange "schedule", 0, -1,
|
108
|
+
initial_schedule = redis.zrange "schedule", 0, -1, withscores: true
|
109
109
|
expect(initial_schedule.size).to be(2)
|
110
110
|
expect(initial_schedule.select {|scheduled_job| JSON.parse(scheduled_job[0])["jid"] == job_id }.size).to be(1)
|
111
111
|
|
@@ -113,7 +113,7 @@ describe Sidekiq::Status do
|
|
113
113
|
# Unused, therefore unfound => false
|
114
114
|
expect(Sidekiq::Status.cancel(unused_id)).to be_falsey
|
115
115
|
|
116
|
-
remaining_schedule = redis.zrange "schedule", 0, -1,
|
116
|
+
remaining_schedule = redis.zrange "schedule", 0, -1, withscores: true
|
117
117
|
expect(remaining_schedule.size).to be(initial_schedule.size - 1)
|
118
118
|
expect(remaining_schedule.select {|scheduled_job| JSON.parse(scheduled_job[0])["jid"] == job_id }.size).to be(0)
|
119
119
|
end
|
@@ -126,14 +126,14 @@ describe Sidekiq::Status do
|
|
126
126
|
returned_job_id = LongJob.perform_at(scheduled_time)
|
127
127
|
expect(returned_job_id).to eq(job_id)
|
128
128
|
|
129
|
-
initial_schedule = redis.zrange "schedule", 0, -1,
|
129
|
+
initial_schedule = redis.zrange "schedule", 0, -1, withscores: true
|
130
130
|
expect(initial_schedule.size).to be(1)
|
131
131
|
# wrong time, therefore unfound => false
|
132
132
|
expect(Sidekiq::Status.cancel(returned_job_id, (scheduled_time + 1))).to be_falsey
|
133
|
-
expect((redis.zrange "schedule", 0, -1,
|
133
|
+
expect((redis.zrange "schedule", 0, -1, withscores: true).size).to be(1)
|
134
134
|
# same id, same time, deletes
|
135
135
|
expect(Sidekiq::Status.cancel(returned_job_id, (scheduled_time))).to be_truthy
|
136
|
-
expect(redis.zrange "schedule", 0, -1,
|
136
|
+
expect(redis.zrange "schedule", 0, -1, withscores: true).to be_empty
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
data/spec/support/test_jobs.rb
CHANGED
@@ -10,6 +10,16 @@ class StubJob
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
class StubNoStatusJob
|
14
|
+
include Sidekiq::Worker
|
15
|
+
|
16
|
+
sidekiq_options 'retry' => false
|
17
|
+
|
18
|
+
def perform(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
13
23
|
class ExpiryJob < StubJob
|
14
24
|
def expiration
|
15
25
|
15
|
@@ -31,6 +41,13 @@ class DataJob < StubJob
|
|
31
41
|
end
|
32
42
|
end
|
33
43
|
|
44
|
+
class CustomDataJob < StubJob
|
45
|
+
def perform
|
46
|
+
store({mister_cat: 'meow'})
|
47
|
+
sleep 0.5
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
34
51
|
class ProgressJob < StubJob
|
35
52
|
def perform
|
36
53
|
total 500
|
@@ -62,6 +79,12 @@ class FailingJob < StubJob
|
|
62
79
|
end
|
63
80
|
end
|
64
81
|
|
82
|
+
class FailingNoStatusJob < StubNoStatusJob
|
83
|
+
def perform
|
84
|
+
raise StandardError
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
65
88
|
class RetryAndFailJob < StubJob
|
66
89
|
sidekiq_options retry: 1
|
67
90
|
|
@@ -76,6 +99,12 @@ class FailingHardJob < StubJob
|
|
76
99
|
end
|
77
100
|
end
|
78
101
|
|
102
|
+
class FailingHardNoStatusJob < StubNoStatusJob
|
103
|
+
def perform
|
104
|
+
raise Exception
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
79
108
|
class ExitedJob < StubJob
|
80
109
|
def perform
|
81
110
|
raise SystemExit
|
data/web/views/status.erb
CHANGED
@@ -65,6 +65,24 @@
|
|
65
65
|
</p>
|
66
66
|
</div>
|
67
67
|
</div>
|
68
|
+
|
69
|
+
<% if @status["custom"].any? %>
|
70
|
+
<hr>
|
71
|
+
<% @status["custom"].each do |key, val| %>
|
72
|
+
<div class="row">
|
73
|
+
<div class="col-sm-2">
|
74
|
+
<strong><%= key %></strong>
|
75
|
+
</div>
|
76
|
+
<div class="col-sm-10">
|
77
|
+
<% if val && val.include?("\n") %>
|
78
|
+
<pre><%= val %></pre>
|
79
|
+
<% else %>
|
80
|
+
<p><%= val || "<i>none</i>" %></p>
|
81
|
+
<% end %>
|
82
|
+
</div>
|
83
|
+
</div>
|
84
|
+
<% end %>
|
85
|
+
<% end %>
|
68
86
|
</div>
|
69
87
|
</div>
|
70
88
|
|
data/web/views/statuses.erb
CHANGED
@@ -38,7 +38,7 @@
|
|
38
38
|
display: flex;
|
39
39
|
align-items: center;
|
40
40
|
}
|
41
|
-
.nav-container .per-page {
|
41
|
+
.nav-container .per-page, .filter-status {
|
42
42
|
display: flex;
|
43
43
|
align-items: center;
|
44
44
|
margin: 20px 0 20px 10px;
|
@@ -57,6 +57,15 @@ function setPerPage(select){
|
|
57
57
|
<h3 class="wi">Recent job statuses</h3>
|
58
58
|
<div class="nav-container">
|
59
59
|
<%= erb :_paging, locals: { url: "#{root_path}statuses" } %>
|
60
|
+
<div class="filter-status">
|
61
|
+
Filter Status:
|
62
|
+
<select class="form-control" onchange="setPerPage(this)">
|
63
|
+
<% (['all', 'complete', 'failed', 'interrupted', 'queued', 'retrying', 'stopped', 'working']).each do |status| %>
|
64
|
+
<option data-url="?<%= qparams(status: status)%>" value="<%= status %>" <%= 'selected="selected"' if status == (params[:status]) %>><%= status %></option>
|
65
|
+
<% end %>
|
66
|
+
</select>
|
67
|
+
</div>
|
68
|
+
|
60
69
|
<div class="per-page">
|
61
70
|
Per page:
|
62
71
|
<select class="form-control" onchange="setPerPage(this)">
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeniy Tsvigun
|
8
8
|
- Kenaniah Cerny
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-06-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: sidekiq
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '5.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '5.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: chronic_duration
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,7 +123,7 @@ dependencies:
|
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
|
-
description:
|
126
|
+
description:
|
127
127
|
email:
|
128
128
|
- utgarda@gmail.com
|
129
129
|
- kenaniah@gmail.com
|
@@ -132,6 +132,7 @@ extensions: []
|
|
132
132
|
extra_rdoc_files: []
|
133
133
|
files:
|
134
134
|
- ".gitignore"
|
135
|
+
- ".gitlab-ci.yml"
|
135
136
|
- ".rspec"
|
136
137
|
- ".travis.yml"
|
137
138
|
- Appraisals
|
@@ -140,9 +141,8 @@ files:
|
|
140
141
|
- LICENSE
|
141
142
|
- README.md
|
142
143
|
- Rakefile
|
143
|
-
- gemfiles/sidekiq_3.x.gemfile
|
144
|
-
- gemfiles/sidekiq_4.x.gemfile
|
145
144
|
- gemfiles/sidekiq_5.x.gemfile
|
145
|
+
- gemfiles/sidekiq_6.x.gemfile
|
146
146
|
- lib/sidekiq-status.rb
|
147
147
|
- lib/sidekiq-status/client_middleware.rb
|
148
148
|
- lib/sidekiq-status/server_middleware.rb
|
@@ -167,11 +167,11 @@ files:
|
|
167
167
|
- web/views/status.erb
|
168
168
|
- web/views/status_not_found.erb
|
169
169
|
- web/views/statuses.erb
|
170
|
-
homepage: http://github.com/
|
170
|
+
homepage: http://github.com/kenaniah/sidekiq-status
|
171
171
|
licenses:
|
172
172
|
- MIT
|
173
173
|
metadata: {}
|
174
|
-
post_install_message:
|
174
|
+
post_install_message:
|
175
175
|
rdoc_options: []
|
176
176
|
require_paths:
|
177
177
|
- lib
|
@@ -186,9 +186,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
186
|
- !ruby/object:Gem::Version
|
187
187
|
version: '0'
|
188
188
|
requirements: []
|
189
|
-
|
190
|
-
|
191
|
-
signing_key:
|
189
|
+
rubygems_version: 3.2.15
|
190
|
+
signing_key:
|
192
191
|
specification_version: 4
|
193
192
|
summary: An extension to the sidekiq message processing to track your jobs
|
194
193
|
test_files:
|