sidekiq-status 1.1.0 → 2.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitlab-ci.yml +17 -0
- data/.travis.yml +10 -6
- data/Appraisals +6 -6
- data/CHANGELOG.md +27 -59
- data/README.md +17 -24
- data/gemfiles/{sidekiq_4.x.gemfile → sidekiq_6.1.gemfile} +1 -1
- data/gemfiles/{sidekiq_3.x.gemfile → sidekiq_6.x.gemfile} +1 -1
- data/lib/sidekiq-status/client_middleware.rb +4 -2
- data/lib/sidekiq-status/server_middleware.rb +1 -1
- data/lib/sidekiq-status/storage.rb +5 -5
- 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/client_middleware_spec.rb +3 -3
- data/spec/lib/sidekiq-status/server_middleware_spec.rb +28 -10
- data/spec/lib/sidekiq-status/web_spec.rb +34 -1
- data/spec/lib/sidekiq-status_spec.rb +6 -6
- data/spec/support/test_jobs.rb +32 -3
- data/web/views/status.erb +26 -7
- data/web/views/status_not_found.erb +3 -2
- data/web/views/statuses.erb +22 -12
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73189e5075131660e13e76ce8e8eeedd84953c90998941dd73a16825dc96d951
|
4
|
+
data.tar.gz: 5923bc75138cee22d8b5edcc5fbb9ad42dad4e0d89f29df74df68656a73adadc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09e500e508e3a0d309e5d817a0fb7e1f58b9013f32284608ae5e2512bd556d07e7846c240789a2df4d5790f0aa183b3623181fd14acb12fd14a863ae354f627e'
|
7
|
+
data.tar.gz: 37b1eb9dec966fc8d8645c0ea4139d9a4cee715aca5c5b988881d63599d77e4d7cc564472a3f72e58923b8fb903ed0254c123821dafa2122c622e0dfc5b1e3ca
|
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,20 @@
|
|
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.1.gemfile
|
10
|
+
- gemfiles/sidekiq_6.x.gemfile
|
11
11
|
before_install:
|
12
12
|
- gem update --system
|
13
13
|
- gem update bundler
|
14
14
|
services: redis
|
15
15
|
notifications:
|
16
16
|
email: false
|
17
|
+
matrix:
|
18
|
+
fast_finish: true
|
19
|
+
allow_failures:
|
20
|
+
- rvm: ruby-head
|
data/Appraisals
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
appraise "sidekiq-
|
2
|
-
gem "sidekiq", "~>
|
1
|
+
appraise "sidekiq-5.x" do
|
2
|
+
gem "sidekiq", "~> 5"
|
3
3
|
end
|
4
4
|
|
5
|
-
appraise "sidekiq-
|
6
|
-
gem "sidekiq", "~>
|
5
|
+
appraise "sidekiq-6.1" do
|
6
|
+
gem "sidekiq", "~> 6.1"
|
7
7
|
end
|
8
8
|
|
9
|
-
appraise "sidekiq-
|
10
|
-
gem "sidekiq", "~>
|
9
|
+
appraise "sidekiq-6.x" do
|
10
|
+
gem "sidekiq", "~> 6"
|
11
11
|
end
|
data/CHANGELOG.md
CHANGED
@@ -1,59 +1,27 @@
|
|
1
|
-
**Version
|
2
|
-
|
3
|
-
|
4
|
-
**Version 1.
|
5
|
-
|
6
|
-
|
7
|
-
**Version 1.
|
8
|
-
|
9
|
-
|
10
|
-
**Version 1.0
|
11
|
-
|
12
|
-
|
13
|
-
**Version 0.
|
14
|
-
|
15
|
-
|
16
|
-
**Version 0.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|
1
|
+
**Version 2.1.3**
|
2
|
+
* Fixes redis deprecation warnings (https://github.com/kenaniah/sidekiq-status/issues/11)
|
3
|
+
|
4
|
+
**Version 2.1.2**
|
5
|
+
* Casts values to strings when HTML-encoding
|
6
|
+
|
7
|
+
**Version 2.1.1**
|
8
|
+
* Ensures parameter outputs are properly HTML-encoded
|
9
|
+
|
10
|
+
**Version 2.1.0**
|
11
|
+
* Adds support for Sidekiq 6.2.2+ (https://github.com/mperham/sidekiq/issues/4955)
|
12
|
+
|
13
|
+
**Version 2.0.2**
|
14
|
+
* Fixes for dark mode theme
|
15
|
+
|
16
|
+
**Version 2.0.1**
|
17
|
+
* Adds support for dark mode to the job status page
|
18
|
+
|
19
|
+
**Version 2.0.0**
|
20
|
+
* Adds support for Ruby 2.7, 3.0
|
21
|
+
* Adds support for Sidekiq 6.x
|
22
|
+
* Removes support for Ruby 2.3, 2.4, 2.5
|
23
|
+
* Removes support for Sidekiq 3.x, 4.x
|
24
|
+
|
25
|
+
**Versions 1.1.4 and prior**
|
26
|
+
|
27
|
+
See https://github.com/utgarda/sidekiq-status/blob/master/CHANGELOG.md.
|
data/README.md
CHANGED
@@ -1,16 +1,11 @@
|
|
1
1
|
# Sidekiq::Status
|
2
|
-
[![Gem Version](https://badge.fury.io/rb/sidekiq-status.svg)](
|
3
|
-
[![
|
4
|
-
[![
|
5
|
-
[![Dependency Status](https://gemnasium.com/utgarda/sidekiq-status.svg)](https://gemnasium.com/utgarda/sidekiq-status)
|
6
|
-
[![Inline docs](http://inch-ci.org/github/utgarda/sidekiq-status.svg?branch=master)](http://inch-ci.org/github/utgarda/sidekiq-status)
|
2
|
+
[![Gem Version](https://badge.fury.io/rb/sidekiq-status.svg)](https://badge.fury.io/rb/sidekiq-status)
|
3
|
+
[![Build Status](https://www.travis-ci.com/kenaniah/sidekiq-status.svg?branch=main)](https://www.travis-ci.com/github/kenaniah/sidekiq-status)
|
4
|
+
[![Inline docs](https://inch-ci.org/github/kenaniah/sidekiq-status.svg?branch=main)](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
|
![Sidekiq Status Web](web/sidekiq-status-web.png)
|
218
211
|
|
219
|
-
|
212
|
+
Information for an individual job may be found at `/statuses/:job_id`.
|
220
213
|
|
221
214
|
![Sidekiq Status Web](web/sidekiq-status-single-web.png)
|
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
|
|
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'sidekiq/api'
|
2
|
+
JOB_CLASS = Sidekiq.constants.include?(:JobRecord) ? Sidekiq::JobRecord : Sidekiq::Job
|
3
|
+
|
2
4
|
module Sidekiq::Status
|
3
5
|
# Should be in the client middleware chain
|
4
6
|
class ClientMiddleware
|
@@ -34,7 +36,7 @@ module Sidekiq::Status
|
|
34
36
|
initial_metadata = {
|
35
37
|
jid: msg['jid'],
|
36
38
|
status: :queued,
|
37
|
-
worker:
|
39
|
+
worker: JOB_CLASS.new(msg, queue).display_class,
|
38
40
|
args: display_args(msg, queue)
|
39
41
|
}
|
40
42
|
store_for_id msg['jid'], initial_metadata, job_class.new.expiration || @expiration, redis_pool
|
@@ -45,7 +47,7 @@ module Sidekiq::Status
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def display_args(msg, queue)
|
48
|
-
job =
|
50
|
+
job = JOB_CLASS.new(msg, queue)
|
49
51
|
return job.display_args.to_a.empty? ? nil : job.display_args.to_json
|
50
52
|
rescue Exception => e
|
51
53
|
# For Sidekiq ~> 2.7
|
@@ -13,10 +13,10 @@ module Sidekiq::Status::Storage
|
|
13
13
|
# @return [String] Redis operation status code
|
14
14
|
def store_for_id(id, status_updates, expiration = nil, redis_pool=nil)
|
15
15
|
redis_connection(redis_pool) do |conn|
|
16
|
-
conn.multi do
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
conn.multi do |pipeline|
|
17
|
+
pipeline.hmset key(id), 'update_time', Time.now.to_i, *(status_updates.to_a.flatten(1))
|
18
|
+
pipeline.expire key(id), (expiration || Sidekiq::Status::DEFAULT_EXPIRY)
|
19
|
+
pipeline.publish "status_updates", id
|
20
20
|
end[0]
|
21
21
|
end
|
22
22
|
end
|
@@ -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 = '
|
8
|
+
gem.homepage = 'https://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'
|
@@ -12,13 +12,13 @@ describe Sidekiq::Status::ClientMiddleware do
|
|
12
12
|
describe "without :expiration parameter" do
|
13
13
|
|
14
14
|
it "sets queued status" do
|
15
|
-
expect(StubJob.perform_async arg1
|
15
|
+
expect(StubJob.perform_async 'arg1' => 'val1').to eq(job_id)
|
16
16
|
expect(redis.hget("sidekiq:status:#{job_id}", :status)).to eq('queued')
|
17
17
|
expect(Sidekiq::Status::queued?(job_id)).to be_truthy
|
18
18
|
end
|
19
19
|
|
20
20
|
it "sets status hash ttl" do
|
21
|
-
expect(StubJob.perform_async arg1
|
21
|
+
expect(StubJob.perform_async 'arg1' => 'val1').to eq(job_id)
|
22
22
|
expect(1..Sidekiq::Status::DEFAULT_EXPIRY).to cover redis.ttl("sidekiq:status:#{job_id}")
|
23
23
|
end
|
24
24
|
|
@@ -50,7 +50,7 @@ describe Sidekiq::Status::ClientMiddleware do
|
|
50
50
|
end
|
51
51
|
|
52
52
|
it "overwrites default expiry value" do
|
53
|
-
StubJob.perform_async arg1
|
53
|
+
StubJob.perform_async 'arg1' => 'val1'
|
54
54
|
expect((Sidekiq::Status::DEFAULT_EXPIRY+1)..huge_expiration).to cover redis.ttl("sidekiq:status:#{job_id}")
|
55
55
|
end
|
56
56
|
|
@@ -10,7 +10,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
10
10
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
11
11
|
start_server do
|
12
12
|
thread = redis_thread 4, "status_updates", "job_messages_#{job_id}"
|
13
|
-
expect(ConfirmationJob.perform_async arg1
|
13
|
+
expect(ConfirmationJob.perform_async 'arg1' => 'val1').to eq(job_id)
|
14
14
|
expect(thread.value).to eq([
|
15
15
|
job_id,
|
16
16
|
job_id,
|
@@ -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
|
@@ -72,7 +90,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
72
90
|
it "sets status hash ttl" do
|
73
91
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
74
92
|
start_server do
|
75
|
-
expect(StubJob.perform_async arg1
|
93
|
+
expect(StubJob.perform_async 'arg1' => 'val1').to eq(job_id)
|
76
94
|
end
|
77
95
|
expect(1..Sidekiq::Status::DEFAULT_EXPIRY).to cover redis.ttl("sidekiq:status:#{job_id}")
|
78
96
|
end
|
@@ -86,7 +104,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
86
104
|
|
87
105
|
it "overwrites default expiry value" do
|
88
106
|
start_server(:expiration => huge_expiration) do
|
89
|
-
StubJob.perform_async arg1
|
107
|
+
StubJob.perform_async 'arg1' => 'val1'
|
90
108
|
end
|
91
109
|
expect((Sidekiq::Status::DEFAULT_EXPIRY-1)..huge_expiration).to cover redis.ttl("sidekiq:status:#{job_id}")
|
92
110
|
end
|
@@ -95,7 +113,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
95
113
|
overwritten_expiration = huge_expiration * 100
|
96
114
|
allow_any_instance_of(StubJob).to receive(:expiration).and_return(overwritten_expiration)
|
97
115
|
start_server(:expiration => huge_expiration) do
|
98
|
-
StubJob.perform_async arg1
|
116
|
+
StubJob.perform_async 'arg1' => 'val1'
|
99
117
|
end
|
100
118
|
expect((huge_expiration+1)..overwritten_expiration).to cover redis.ttl("sidekiq:status:#{job_id}")
|
101
119
|
end
|
@@ -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')
|
@@ -39,10 +61,21 @@ describe 'sidekiq status web' do
|
|
39
61
|
get "/statuses/#{job_id}"
|
40
62
|
expect(last_response).to be_ok
|
41
63
|
expect(last_response.body).to match(/#{job_id}/)
|
42
|
-
expect(last_response.body).to match(/1
|
64
|
+
expect(last_response.body).to match(/1,"another argument"/)
|
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
|
@@ -159,7 +159,7 @@ describe Sidekiq::Status do
|
|
159
159
|
end
|
160
160
|
|
161
161
|
it "retries failed jobs" do
|
162
|
-
allow(SecureRandom).to receive(:hex).and_return(retried_job_id)
|
162
|
+
allow(SecureRandom).to receive(:hex).exactly(3).times.and_return(retried_job_id)
|
163
163
|
start_server do
|
164
164
|
expect(capture_status_updates(3) {
|
165
165
|
expect(RetriedJob.perform_async()).to eq(retried_job_id)
|
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
|
@@ -90,13 +119,13 @@ end
|
|
90
119
|
|
91
120
|
class RetriedJob < StubJob
|
92
121
|
|
93
|
-
sidekiq_options
|
122
|
+
sidekiq_options retry: true
|
94
123
|
sidekiq_retry_in do |count| 3 end # 3 second delay > job timeout in test suite
|
95
124
|
|
96
|
-
def perform
|
125
|
+
def perform
|
97
126
|
Sidekiq.redis do |conn|
|
98
127
|
key = "RetriedJob_#{jid}"
|
99
|
-
|
128
|
+
if [0, false].include? conn.exists(key)
|
100
129
|
conn.set key, 'tried'
|
101
130
|
raise StandardError
|
102
131
|
end
|
data/web/views/status.erb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
<% require 'cgi'; def h(v); CGI.escape_html(v.to_s); end %>
|
1
2
|
<style>
|
2
3
|
.progress {
|
3
4
|
background-color: #C8E1ED;
|
@@ -14,9 +15,9 @@
|
|
14
15
|
</style>
|
15
16
|
|
16
17
|
<h3>
|
17
|
-
Job Status: <%= @status["jid"] %>
|
18
|
-
<span class='label label-<%= @status["label"] %>'>
|
19
|
-
<%= @status["status"] %>
|
18
|
+
Job Status: <%= h @status["jid"] %>
|
19
|
+
<span class='label label-<%= h @status["label"] %>'>
|
20
|
+
<%= h @status["status"] %>
|
20
21
|
</span>
|
21
22
|
</h3>
|
22
23
|
|
@@ -28,16 +29,16 @@
|
|
28
29
|
</div>
|
29
30
|
</div>
|
30
31
|
|
31
|
-
<div class="panel panel-default">
|
32
|
+
<div class="panel panel-default" style="background-color: inherit">
|
32
33
|
<div class="panel-body">
|
33
|
-
<h4><%= @status["worker"] %></h4>
|
34
|
+
<h4><%= h @status["worker"] %></h4>
|
34
35
|
|
35
36
|
<div class="row">
|
36
37
|
<div class="col-sm-2">
|
37
38
|
<strong>Arguments</strong>
|
38
39
|
</div>
|
39
40
|
<div class="col-sm-10">
|
40
|
-
<p><%= @status["args"].empty? ? "<i>none</i>" : @status["args"] %></p>
|
41
|
+
<p><%= @status["args"].empty? ? "<i>none</i>" : h(@status["args"]) %></p>
|
41
42
|
</div>
|
42
43
|
</div>
|
43
44
|
|
@@ -46,7 +47,7 @@
|
|
46
47
|
<strong>Message</strong>
|
47
48
|
</div>
|
48
49
|
<div class="col-sm-10">
|
49
|
-
<p><%= @status["message"] || "<i>none</i>" %></p>
|
50
|
+
<p><%= h(@status["message"]) || "<i>none</i>" %></p>
|
50
51
|
</div>
|
51
52
|
</div>
|
52
53
|
|
@@ -65,6 +66,24 @@
|
|
65
66
|
</p>
|
66
67
|
</div>
|
67
68
|
</div>
|
69
|
+
|
70
|
+
<% if @status["custom"].any? %>
|
71
|
+
<hr>
|
72
|
+
<% @status["custom"].each do |key, val| %>
|
73
|
+
<div class="row">
|
74
|
+
<div class="col-sm-2">
|
75
|
+
<strong><%= key %></strong>
|
76
|
+
</div>
|
77
|
+
<div class="col-sm-10">
|
78
|
+
<% if val && val.include?("\n") %>
|
79
|
+
<pre><%= h val %></pre>
|
80
|
+
<% else %>
|
81
|
+
<p><%= h(val) || "<i>none</i>" %></p>
|
82
|
+
<% end %>
|
83
|
+
</div>
|
84
|
+
</div>
|
85
|
+
<% end %>
|
86
|
+
<% end %>
|
68
87
|
</div>
|
69
88
|
</div>
|
70
89
|
|
@@ -1,5 +1,6 @@
|
|
1
|
-
|
1
|
+
<% require 'cgi'; def h(v); CGI.escape_html(v.to_s); end %>
|
2
|
+
<h3>Job Status: <%= h params[:jid] %></h3>
|
2
3
|
|
3
|
-
<div
|
4
|
+
<div role="alert">
|
4
5
|
<strong>Uh oh!</strong> That job can't be found. It may have expired already.
|
5
6
|
</div>
|
data/web/views/statuses.erb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
<% require 'cgi'; def h(v); CGI.escape_html(v.to_s); end %>
|
1
2
|
<style>
|
2
3
|
.progress {
|
3
4
|
background-color: #C8E1ED;
|
@@ -38,7 +39,7 @@
|
|
38
39
|
display: flex;
|
39
40
|
align-items: center;
|
40
41
|
}
|
41
|
-
.nav-container .per-page {
|
42
|
+
.nav-container .per-page, .filter-status {
|
42
43
|
display: flex;
|
43
44
|
align-items: center;
|
44
45
|
margin: 20px 0 20px 10px;
|
@@ -57,6 +58,15 @@ function setPerPage(select){
|
|
57
58
|
<h3 class="wi">Recent job statuses</h3>
|
58
59
|
<div class="nav-container">
|
59
60
|
<%= erb :_paging, locals: { url: "#{root_path}statuses" } %>
|
61
|
+
<div class="filter-status">
|
62
|
+
Filter Status:
|
63
|
+
<select class="form-control" onchange="setPerPage(this)">
|
64
|
+
<% (['all', 'complete', 'failed', 'interrupted', 'queued', 'retrying', 'stopped', 'working']).each do |status| %>
|
65
|
+
<option data-url="?<%= qparams(status: status)%>" value="<%= status %>" <%= 'selected="selected"' if status == (params[:status]) %>><%= status %></option>
|
66
|
+
<% end %>
|
67
|
+
</select>
|
68
|
+
</div>
|
69
|
+
|
60
70
|
<div class="per-page">
|
61
71
|
Per page:
|
62
72
|
<select class="form-control" onchange="setPerPage(this)">
|
@@ -67,11 +77,11 @@ function setPerPage(select){
|
|
67
77
|
</div>
|
68
78
|
</div>
|
69
79
|
</div>
|
70
|
-
<table class="table table-hover table-bordered table-striped
|
80
|
+
<table class="table table-hover table-bordered table-striped">
|
71
81
|
<tr>
|
72
|
-
<% @headers.each do |
|
73
|
-
<th class="header <%= h[:class] %> header_<%= h[:id] %>">
|
74
|
-
<a href="<%= h[:url] %>"><%= h[:name] %></a>
|
82
|
+
<% @headers.each do |hdr| %>
|
83
|
+
<th class="header <%= h hdr[:class] %> header_<%= h hdr[:id] %>">
|
84
|
+
<a href="<%= h hdr[:url] %>"><%= h hdr[:name] %></a>
|
75
85
|
</th>
|
76
86
|
<% end %>
|
77
87
|
<th class="header">
|
@@ -81,13 +91,13 @@ function setPerPage(select){
|
|
81
91
|
<% @statuses.each do |container| %>
|
82
92
|
<tr>
|
83
93
|
<td>
|
84
|
-
<div title='<%= container["jid"] %>'><a href="<%= root_path %>statuses/<%= container["jid"] %>"><%= container["worker"] %></a></div>
|
94
|
+
<div title='<%= h container["jid"] %>'><a href="<%= root_path %>statuses/<%= h container["jid"] %>"><%= h container["worker"] %></a></div>
|
85
95
|
</td>
|
86
96
|
<td>
|
87
|
-
<div class='args' title='<%= container["jid"] %>'><%= container["args"] %></div>
|
97
|
+
<div class='args' title='<%= h container["jid"] %>'><%= h container["args"] %></div>
|
88
98
|
</td>
|
89
99
|
<td style='text-align: center;'>
|
90
|
-
<div class='label label-<%= container["label"] %>'><%= container["status"] %></div>
|
100
|
+
<div class='label label-<%= h container["label"] %>'><%= h container["status"] %></div>
|
91
101
|
</td>
|
92
102
|
<% secs = Time.now.to_i - container["update_time"].to_i %>
|
93
103
|
<td style='text-align: center; white-space: nowrap;' title="<%= Time.at(container["update_time"].to_i) %>">
|
@@ -100,11 +110,11 @@ function setPerPage(select){
|
|
100
110
|
<td>
|
101
111
|
<div class="progress progress-striped" style="margin-bottom: 0">
|
102
112
|
<div class='message' style='text-align:right; padding-right:0.5em; background-color: transparent; float:right;'>
|
103
|
-
<%= container["message"] %>
|
113
|
+
<%= h container["message"] %>
|
104
114
|
</div>
|
105
115
|
<% if container["pct_complete"].to_i > 0 %>
|
106
|
-
<div class="bar message" style="width: <%= container["pct_complete"] %>%;">
|
107
|
-
<%= container["pct_complete"] %>%
|
116
|
+
<div class="bar message" style="width: <%= h container["pct_complete"] %>%;">
|
117
|
+
<%= h container["pct_complete"] %>%
|
108
118
|
</div>
|
109
119
|
<% end %>
|
110
120
|
</div>
|
@@ -112,7 +122,7 @@ function setPerPage(select){
|
|
112
122
|
<td>
|
113
123
|
<div class="actions">
|
114
124
|
<form action="statuses" method="post">
|
115
|
-
<input type="hidden" name="jid" value="<%= container["jid"] %>" />
|
125
|
+
<input type="hidden" name="jid" value="<%= h container["jid"] %>" />
|
116
126
|
<%= csrf_tag %>
|
117
127
|
<% if container["status"] == "complete" %>
|
118
128
|
<input type="hidden" name="_method" value="delete" />
|
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.1.3
|
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: 2022-02-03 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,9 @@ 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.1.gemfile
|
146
|
+
- gemfiles/sidekiq_6.x.gemfile
|
146
147
|
- lib/sidekiq-status.rb
|
147
148
|
- lib/sidekiq-status/client_middleware.rb
|
148
149
|
- lib/sidekiq-status/server_middleware.rb
|
@@ -167,11 +168,11 @@ files:
|
|
167
168
|
- web/views/status.erb
|
168
169
|
- web/views/status_not_found.erb
|
169
170
|
- web/views/statuses.erb
|
170
|
-
homepage:
|
171
|
+
homepage: https://github.com/kenaniah/sidekiq-status
|
171
172
|
licenses:
|
172
173
|
- MIT
|
173
174
|
metadata: {}
|
174
|
-
post_install_message:
|
175
|
+
post_install_message:
|
175
176
|
rdoc_options: []
|
176
177
|
require_paths:
|
177
178
|
- lib
|
@@ -186,9 +187,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
186
187
|
- !ruby/object:Gem::Version
|
187
188
|
version: '0'
|
188
189
|
requirements: []
|
189
|
-
|
190
|
-
|
191
|
-
signing_key:
|
190
|
+
rubygems_version: 3.2.32
|
191
|
+
signing_key:
|
192
192
|
specification_version: 4
|
193
193
|
summary: An extension to the sidekiq message processing to track your jobs
|
194
194
|
test_files:
|