sidekiq-status 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -7
- data/CHANGELOG.md +18 -8
- data/Gemfile +0 -4
- data/README.md +33 -7
- data/lib/sidekiq-status.rb +7 -2
- data/lib/sidekiq-status/client_middleware.rb +13 -4
- data/lib/sidekiq-status/storage.rb +9 -0
- data/lib/sidekiq-status/testing/inline.rb +6 -0
- data/lib/sidekiq-status/version.rb +1 -1
- data/lib/sidekiq-status/web.rb +21 -8
- data/lib/sidekiq-status/worker.rb +2 -2
- data/sidekiq-status.gemspec +1 -0
- data/spec/environment.rb +1 -0
- data/spec/lib/sidekiq-status/client_middleware_spec.rb +0 -3
- data/spec/lib/sidekiq-status/server_middleware_spec.rb +4 -9
- data/spec/lib/sidekiq-status/web_spec.rb +29 -15
- data/spec/lib/sidekiq-status_spec.rb +17 -5
- data/spec/spec_helper.rb +12 -4
- data/spec/support/test_jobs.rb +3 -1
- data/web/sidekiq-status-single-web.png +0 -0
- data/web/views/status.erb +73 -0
- data/web/views/status_not_found.erb +5 -0
- data/web/views/statuses.erb +19 -12
- metadata +22 -4
- data/gemfiles/Gemfile.sidekiq-2 +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1750cf2e429082ad9d404598e45fe7bf15bb31cc
|
4
|
+
data.tar.gz: 708de7f5f0a83d59fec644600f2a4e70e99c89d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7228891c5252a1df3da9ad85942552f5426a466d18ddc6b9e963ad3ec6f91512ecaadeb8e0ff00c09f36d2c9a044cfb44619271b772637b88c044868d15fdc4c
|
7
|
+
data.tar.gz: 56a416d652d875528fd64cebaa490fc3ae173ba96d8ea080c7d2d202a67ecdc11d365c66d3d4cac4691977a5d8d2b006addc0f84cbb2a7fca52ad3fa5cb07530
|
data/.travis.yml
CHANGED
@@ -1,16 +1,11 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- 2.0
|
4
|
-
- 2.1
|
5
3
|
- 2.2
|
6
|
-
-
|
4
|
+
- 2.3
|
5
|
+
- 2.4
|
7
6
|
gemfile:
|
8
|
-
- gemfiles/Gemfile.sidekiq-2
|
9
7
|
- Gemfile
|
10
8
|
before_install:
|
11
9
|
- gem update --system
|
12
10
|
- gem update bundler
|
13
11
|
services: redis
|
14
|
-
matrix:
|
15
|
-
allow_failures:
|
16
|
-
- rvm: rbx-2
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,26 @@
|
|
1
|
+
Version 0.7.0
|
2
|
+
+ Sidekiq 4.2 and 5 now supported
|
3
|
+
+ Added full support for ActiveJob
|
4
|
+
+ Updated Web UI
|
5
|
+
+ Styling updated to stay consistent with Sidekiq UI
|
6
|
+
+ Added header sorting
|
7
|
+
+ Fixed argument formatting
|
8
|
+
+ Times now display using natural language via ChronicDuration
|
9
|
+
+ Test suite fixed
|
10
|
+
|
1
11
|
Version 0.6.0
|
2
|
-
+ Updated Web UI
|
12
|
+
+ Updated Web UI
|
3
13
|
+ Will have all job statuses, previously it was showing only :working status
|
4
|
-
+ Bootstrap lables instead of badges for status
|
5
|
-
+ Added Arguments column to statuses page
|
6
|
-
+ New :interrupted status added
|
14
|
+
+ Bootstrap lables instead of badges for status
|
15
|
+
+ Added Arguments column to statuses page
|
16
|
+
+ New :interrupted status added
|
7
17
|
+ Added way to specify :expiration for Sidekiq::Status::ClientMiddleware
|
8
|
-
+ Bug fixes & Code cleaup
|
18
|
+
+ Bug fixes & Code cleaup
|
9
19
|
|
10
|
-
Version 0.5.3
|
20
|
+
Version 0.5.3
|
11
21
|
+ some tweaks in web UI, separate redis namespace
|
12
22
|
|
13
|
-
Version 0.5.2
|
23
|
+
Version 0.5.2
|
14
24
|
+ Sidekiq versions up to 3.3.* supported, jobs sorting options in web UI, more ruby versions
|
15
25
|
|
16
26
|
Version 0.5.1
|
@@ -20,4 +30,4 @@ Version 0.5.0
|
|
20
30
|
+ Sidekiq v3 support, redis pools support
|
21
31
|
|
22
32
|
Version 0.4.0
|
23
|
-
+ WebUI added, per-worker expiration setting enabled
|
33
|
+
+ WebUI added, per-worker expiration setting enabled
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -10,7 +10,18 @@ by [resque-status](http://github.com/quirkey/resque-status) and mostly copying i
|
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
-
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'sidekiq-status'
|
17
|
+
```
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
gem install sidekiq-status
|
14
25
|
|
15
26
|
## Usage
|
16
27
|
|
@@ -115,7 +126,7 @@ class MyJob
|
|
115
126
|
store vino: 'veritas'
|
116
127
|
|
117
128
|
# a way of retrieving said data
|
118
|
-
# remember that retrieved data is always
|
129
|
+
# remember that retrieved data is always String|nil
|
119
130
|
vino = retrieve :vino
|
120
131
|
end
|
121
132
|
end
|
@@ -145,10 +156,18 @@ Sidekiq::Status.unschedule '' #=> false
|
|
145
156
|
```
|
146
157
|
Important: If you try any of the status method after the expiration time for scheduled jobs, will result into `nil` or `false`. But job will be in sidekiq's scheduled queue and will execute normally, once job is started on scheduled time you will get status info for job till expiration time defined on `Sidekiq::Status::ServerMiddleware`.
|
147
158
|
|
159
|
+
### Deleting Status by Job ID
|
160
|
+
```ruby
|
161
|
+
# returns number of keys/jobs that were removed
|
162
|
+
Sidekiq::Status.delete(job_id) #=> 1
|
163
|
+
Sidekiq::Status.delete(bad_job_id) #=> 0
|
164
|
+
```
|
165
|
+
|
148
166
|
### Sidekiq web integration
|
149
167
|
|
150
|
-
Sidekiq::Status also provides an extension to Sidekiq web interface with a `/statuses`.
|
151
|
-
![Sidekiq Status Web](
|
168
|
+
Sidekiq::Status also provides an extension to Sidekiq web interface with an index at `/statuses` and a single job at `/statuses/123`.
|
169
|
+
![Sidekiq Status Web](web/sidekiq-status-web.png)
|
170
|
+
![Sidekiq Status Web](web/sidekiq-status-single-web.png)
|
152
171
|
|
153
172
|
Setup Sidekiq web interface according to Sidekiq documentation and add the Sidekiq::Status::Web require:
|
154
173
|
|
@@ -177,9 +196,16 @@ To use `sidekiq-status` inlining, require it too in your `{test,spec}_helper.rb`
|
|
177
196
|
|
178
197
|
`require 'sidekiq-status/testing/inline'`
|
179
198
|
|
199
|
+
## Contributing
|
200
|
+
|
201
|
+
Bug reports and pull requests are welcome. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
180
202
|
|
181
|
-
|
182
|
-
|
203
|
+
1. Fork it
|
204
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
205
|
+
3. Commit your changes along with test cases (`git commit -am 'Add some feature'`)
|
206
|
+
4. If possible squash your commits to one commit if they all belong to same feature.
|
207
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
208
|
+
6. Create new Pull Request.
|
183
209
|
|
184
210
|
## Thanks
|
185
211
|
* Pramod Shinde
|
@@ -194,4 +220,4 @@ To use `sidekiq-status` inlining, require it too in your `{test,spec}_helper.rb`
|
|
194
220
|
|
195
221
|
## License
|
196
222
|
MIT License , see LICENSE for more details.
|
197
|
-
© 2012 -
|
223
|
+
© 2012 - 2016 Evgeniy Tsvigun
|
data/lib/sidekiq-status.rb
CHANGED
@@ -4,6 +4,7 @@ require 'sidekiq-status/worker'
|
|
4
4
|
require 'sidekiq-status/client_middleware'
|
5
5
|
require 'sidekiq-status/server_middleware'
|
6
6
|
require 'sidekiq-status/web' if defined?(Sidekiq::Web)
|
7
|
+
require 'chronic_duration'
|
7
8
|
|
8
9
|
module Sidekiq::Status
|
9
10
|
extend Storage
|
@@ -21,8 +22,8 @@ module Sidekiq::Status
|
|
21
22
|
# Get all status fields for a job
|
22
23
|
# @params [String] id job id returned by async_perform
|
23
24
|
# @return [Hash] hash of all fields stored for the job
|
24
|
-
def get_all(
|
25
|
-
read_hash_for_id(
|
25
|
+
def get_all(job_id)
|
26
|
+
read_hash_for_id(job_id)
|
26
27
|
end
|
27
28
|
|
28
29
|
def status(job_id)
|
@@ -34,6 +35,10 @@ module Sidekiq::Status
|
|
34
35
|
delete_and_unschedule(job_id, job_unix_time)
|
35
36
|
end
|
36
37
|
|
38
|
+
def delete(job_id)
|
39
|
+
delete_status(job_id)
|
40
|
+
end
|
41
|
+
|
37
42
|
alias_method :unschedule, :cancel
|
38
43
|
|
39
44
|
STATUS.each do |name|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'sidekiq/api'
|
1
2
|
module Sidekiq::Status
|
2
3
|
# Should be in the client middleware chain
|
3
4
|
class ClientMiddleware
|
@@ -17,14 +18,22 @@ module Sidekiq::Status
|
|
17
18
|
# @param [String] queue the queue's name
|
18
19
|
# @param [ConnectionPool] redis_pool optional redis connection pool
|
19
20
|
def call(worker_class, msg, queue, redis_pool=nil)
|
20
|
-
initial_metadata = {
|
21
|
+
initial_metadata = {
|
21
22
|
jid: msg['jid'],
|
22
23
|
status: :queued,
|
23
|
-
worker:
|
24
|
-
args: msg
|
24
|
+
worker: Sidekiq::Job.new(msg, queue).display_class,
|
25
|
+
args: display_args(msg, queue)
|
25
26
|
}
|
26
27
|
store_for_id msg['jid'], initial_metadata, @expiration, redis_pool
|
27
28
|
yield
|
28
29
|
end
|
30
|
+
|
31
|
+
def display_args(msg, queue)
|
32
|
+
job = Sidekiq::Job.new(msg, queue)
|
33
|
+
return job.display_args.to_a.empty? ? nil : job.display_args.to_json
|
34
|
+
rescue Exception => e
|
35
|
+
# For Sidekiq ~> 2.7
|
36
|
+
return msg['args'].to_a.empty? ? nil : msg['args'].to_json
|
37
|
+
end
|
29
38
|
end
|
30
|
-
end
|
39
|
+
end
|
@@ -52,6 +52,15 @@ module Sidekiq::Status::Storage
|
|
52
52
|
false
|
53
53
|
end
|
54
54
|
|
55
|
+
# Deletes status hash info for given job id
|
56
|
+
# @param[String] job id
|
57
|
+
# @retrun [Integer] number of keys that were removed
|
58
|
+
def delete_status(id)
|
59
|
+
redis_connection do |conn|
|
60
|
+
conn.del(key(id))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
55
64
|
# Gets a single valued from job status hash
|
56
65
|
# @param [String] id job id
|
57
66
|
# @param [String] Symbol field fetched field name
|
data/lib/sidekiq-status/web.rb
CHANGED
@@ -22,7 +22,7 @@ module Sidekiq::Status
|
|
22
22
|
|
23
23
|
def pct_complete(status)
|
24
24
|
return 100 if status['status'] == 'complete'
|
25
|
-
Sidekiq::Status::pct_complete(status['jid'])
|
25
|
+
Sidekiq::Status::pct_complete(status['jid']) || 0
|
26
26
|
end
|
27
27
|
|
28
28
|
def status_label(status)
|
@@ -64,20 +64,22 @@ module Sidekiq::Status
|
|
64
64
|
sort_dir = "desc"
|
65
65
|
@statuses = @statuses.sort { |y,x| x.send(sort_by) <=> y.send(sort_by) }
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
working_jobs = @statuses.select{|job| job.status == "working"}
|
69
|
-
|
70
|
-
|
69
|
+
size = params[:size] ? params[:size].to_i : 25
|
70
|
+
if working_jobs.size >= size
|
71
|
+
@statuses = working_jobs
|
71
72
|
else
|
72
|
-
|
73
|
+
@statuses = (@statuses.size >= size) ? @statuses.take(size) : @statuses
|
73
74
|
end
|
74
|
-
|
75
|
+
|
76
|
+
|
75
77
|
@headers = [
|
76
|
-
{ id: "worker", name: "Worker/
|
78
|
+
{ id: "worker", name: "Worker / JID", class: nil, url: nil},
|
79
|
+
{ id: "args", name: "Arguments", class: nil, url: nil},
|
77
80
|
{ id: "status", name: "Status", class: nil, url: nil},
|
78
81
|
{ id: "update_time", name: "Last Updated", class: nil, url: nil},
|
79
82
|
{ id: "pct_complete", name: "Progress", class: nil, url: nil},
|
80
|
-
{ id: "message", name: "Message", class: nil, url: nil}
|
81
83
|
]
|
82
84
|
|
83
85
|
@headers.each do |h|
|
@@ -89,6 +91,17 @@ module Sidekiq::Status
|
|
89
91
|
|
90
92
|
erb(sidekiq_status_template(:statuses))
|
91
93
|
end
|
94
|
+
|
95
|
+
app.get '/statuses/:jid' do
|
96
|
+
job = Sidekiq::Status::get_all params['jid']
|
97
|
+
|
98
|
+
if job.empty?
|
99
|
+
halt [404, {"Content-Type" => "text/html"}, [erb(sidekiq_status_template(:status_not_found))]]
|
100
|
+
else
|
101
|
+
@status = OpenStruct.new(add_details_to_status(job))
|
102
|
+
erb(sidekiq_status_template(:status))
|
103
|
+
end
|
104
|
+
end
|
92
105
|
end
|
93
106
|
end
|
94
107
|
end
|
@@ -11,14 +11,14 @@ module Sidekiq::Status::Worker
|
|
11
11
|
# @param [Hash] status_updates updated values
|
12
12
|
# @return [String] Redis operation status code
|
13
13
|
def store(hash)
|
14
|
-
store_for_id @jid, hash, @expiration
|
14
|
+
store_for_id @provider_job_id || @job_id || @jid, hash, @expiration
|
15
15
|
end
|
16
16
|
|
17
17
|
# Read value from job status hash
|
18
18
|
# @param String|Symbol hask key
|
19
19
|
# @return [String]
|
20
20
|
def retrieve(name)
|
21
|
-
read_field_for_id @jid, name
|
21
|
+
read_field_for_id @provider_job_id || @job_id || @jid, name
|
22
22
|
end
|
23
23
|
|
24
24
|
# Sets current task progress
|
data/sidekiq-status.gemspec
CHANGED
@@ -15,6 +15,7 @@ Gem::Specification.new do |gem|
|
|
15
15
|
gem.version = Sidekiq::Status::VERSION
|
16
16
|
|
17
17
|
gem.add_dependency 'sidekiq', '>= 2.7'
|
18
|
+
gem.add_dependency 'chronic_duration'
|
18
19
|
gem.add_development_dependency 'rack-test'
|
19
20
|
gem.add_development_dependency 'rake'
|
20
21
|
gem.add_development_dependency 'rspec'
|
data/spec/environment.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# This file has been intentionally left blank
|
@@ -5,9 +5,6 @@ describe Sidekiq::Status::ClientMiddleware do
|
|
5
5
|
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
6
6
|
let!(:job_id) { SecureRandom.hex(12) }
|
7
7
|
|
8
|
-
# Clean Redis before each test
|
9
|
-
before { redis.flushall }
|
10
|
-
|
11
8
|
describe "#call" do
|
12
9
|
before { client_middleware }
|
13
10
|
it "sets queued status" do
|
@@ -5,11 +5,6 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
5
5
|
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
6
6
|
let!(:job_id) { SecureRandom.hex(12) }
|
7
7
|
|
8
|
-
# Clean Redis before each test
|
9
|
-
# Seems like flushall has no effect on recently published messages,
|
10
|
-
# so we should wait till they expire
|
11
|
-
before { redis.flushall; sleep 0.1 }
|
12
|
-
|
13
8
|
describe "#call" do
|
14
9
|
it "sets working/complete status" do
|
15
10
|
thread = confirmations_thread 4, "status_updates", "job_messages_#{job_id}"
|
@@ -35,8 +30,8 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
35
30
|
expect(Sidekiq::Status::failed?(job_id)).to be_truthy
|
36
31
|
end
|
37
32
|
|
38
|
-
context "sets interrupted status" do
|
39
|
-
it "on system exit signal" do
|
33
|
+
context "sets interrupted status" do
|
34
|
+
it "on system exit signal" do
|
40
35
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
41
36
|
start_server do
|
42
37
|
expect(capture_status_updates(3) {
|
@@ -47,7 +42,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
47
42
|
expect(Sidekiq::Status::interrupted?(job_id)).to be_truthy
|
48
43
|
end
|
49
44
|
|
50
|
-
it "on interrupt signal" do
|
45
|
+
it "on interrupt signal" do
|
51
46
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
52
47
|
start_server do
|
53
48
|
expect(capture_status_updates(3) {
|
@@ -79,7 +74,7 @@ describe Sidekiq::Status::ServerMiddleware do
|
|
79
74
|
start_server(:expiration => huge_expiration) do
|
80
75
|
StubJob.perform_async(:arg1 => 'val1')
|
81
76
|
end
|
82
|
-
expect((Sidekiq::Status::DEFAULT_EXPIRY
|
77
|
+
expect((Sidekiq::Status::DEFAULT_EXPIRY-1)..huge_expiration).to cover redis.ttl("sidekiq:status:#{job_id}")
|
83
78
|
end
|
84
79
|
|
85
80
|
it "can be overwritten by worker expiration method" do
|
@@ -8,30 +8,44 @@ describe 'sidekiq status web' do
|
|
8
8
|
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
9
9
|
let!(:job_id) { SecureRandom.hex(12) }
|
10
10
|
|
11
|
-
# Clean Redis before each test
|
12
|
-
# Seems like flushall has no effect on recently published messages,
|
13
|
-
# so we should wait till they expire
|
14
|
-
before { redis.flushall; sleep 0.1 }
|
15
|
-
|
16
11
|
def app
|
17
12
|
Sidekiq::Web
|
18
13
|
end
|
19
14
|
|
20
|
-
|
15
|
+
before do
|
21
16
|
client_middleware
|
22
17
|
allow(SecureRandom).to receive(:hex).and_return(job_id)
|
18
|
+
end
|
19
|
+
|
20
|
+
around { |example| start_server(&example) }
|
21
|
+
|
22
|
+
it 'shows the list of jobs in progress' do
|
23
|
+
capture_status_updates(2) do
|
24
|
+
expect(LongJob.perform_async(1)).to eq(job_id)
|
25
|
+
end
|
23
26
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
get '/statuses'
|
28
|
+
expect(last_response).to be_ok
|
29
|
+
expect(last_response.body).to match(/#{job_id}/)
|
30
|
+
expect(last_response.body).to match(/LongJob/)
|
31
|
+
expect(last_response.body).to match(/working/)
|
32
|
+
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
expect(last_response.body).to match(/LongJob/)
|
33
|
-
expect(last_response.body).to match(/working/)
|
34
|
+
it 'shows a single job in progress' do
|
35
|
+
capture_status_updates(2) do
|
36
|
+
LongJob.perform_async(1, 'another argument')
|
34
37
|
end
|
38
|
+
|
39
|
+
get "/statuses/#{job_id}"
|
40
|
+
expect(last_response).to be_ok
|
41
|
+
expect(last_response.body).to match(/#{job_id}/)
|
42
|
+
expect(last_response.body).to match(/1,"another argument"/)
|
43
|
+
expect(last_response.body).to match(/working/)
|
35
44
|
end
|
36
45
|
|
46
|
+
it 'show an error when the requested job ID is not found' do
|
47
|
+
get '/statuses/12345'
|
48
|
+
expect(last_response).to be_not_found
|
49
|
+
expect(last_response.body).to match(/That job can't be found/)
|
50
|
+
end
|
37
51
|
end
|
@@ -9,11 +9,6 @@ describe Sidekiq::Status do
|
|
9
9
|
let!(:plain_sidekiq_job_id) { SecureRandom.hex(12) }
|
10
10
|
let!(:retried_job_id) { SecureRandom.hex(12) }
|
11
11
|
|
12
|
-
# Clean Redis before each test
|
13
|
-
# Seems like flushall has no effect on recently published messages,
|
14
|
-
# so we should wait till they expire
|
15
|
-
before { redis.flushall; sleep 0.1 }
|
16
|
-
|
17
12
|
describe ".status, .working?, .complete?" do
|
18
13
|
it "gets job status by id as symbol" do
|
19
14
|
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
@@ -82,6 +77,23 @@ describe Sidekiq::Status do
|
|
82
77
|
end
|
83
78
|
end
|
84
79
|
|
80
|
+
describe '.delete' do
|
81
|
+
it 'deletes the status hash for given job id' do
|
82
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
83
|
+
start_server do
|
84
|
+
expect(capture_status_updates(2) {
|
85
|
+
expect(LongJob.perform_async(1)).to eq(job_id)
|
86
|
+
}).to eq([job_id]*2)
|
87
|
+
end
|
88
|
+
expect(Sidekiq::Status.delete(job_id)).to eq(1)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should not raise error while deleting status hash if invalid job id' do
|
92
|
+
allow(SecureRandom).to receive(:hex).once.and_return(job_id)
|
93
|
+
expect(Sidekiq::Status.delete(job_id)).to eq(0)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
85
97
|
describe ".cancel" do
|
86
98
|
it "cancels a job by id" do
|
87
99
|
allow(SecureRandom).to receive(:hex).twice.and_return(job_id, job_id_1)
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
require "rspec"
|
2
2
|
|
3
|
-
require 'celluloid'
|
4
3
|
require 'sidekiq'
|
5
4
|
require 'sidekiq/processor'
|
6
5
|
require 'sidekiq/manager'
|
7
6
|
require 'sidekiq-status'
|
8
7
|
|
8
|
+
# Clears jobs before every test
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.before(:each) do
|
11
|
+
Sidekiq.redis { |conn| conn.flushall }
|
12
|
+
sleep 0.05
|
13
|
+
end
|
14
|
+
end
|
9
15
|
|
10
16
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
11
17
|
|
12
|
-
def client_middleware(client_middleware_options={})
|
18
|
+
def client_middleware(client_middleware_options={})
|
13
19
|
Sidekiq.configure_client do |config|
|
14
20
|
config.client_middleware do |chain|
|
15
21
|
chain.add Sidekiq::Status::ClientMiddleware, client_middleware_options
|
@@ -52,7 +58,9 @@ def start_server(server_middleware_options={})
|
|
52
58
|
$stderr.reopen File::NULL, 'w'
|
53
59
|
require 'sidekiq/cli'
|
54
60
|
Sidekiq.options[:queues] << 'default'
|
55
|
-
Sidekiq.options[:require] =
|
61
|
+
Sidekiq.options[:require] = File.expand_path('environment.rb', File.dirname(__FILE__))
|
62
|
+
Sidekiq.options[:timeout] = 1
|
63
|
+
Sidekiq.options[:concurrency] = 5
|
56
64
|
Sidekiq.configure_server do |config|
|
57
65
|
config.redis = Sidekiq::RedisConnection.create
|
58
66
|
config.server_middleware do |chain|
|
@@ -65,7 +73,7 @@ def start_server(server_middleware_options={})
|
|
65
73
|
yield
|
66
74
|
sleep 0.1
|
67
75
|
Process.kill 'TERM', pid
|
68
|
-
Timeout::timeout(
|
76
|
+
Timeout::timeout(5) { Process.wait pid } rescue Timeout::Error
|
69
77
|
ensure
|
70
78
|
Process.kill 'KILL', pid rescue "OK" # it's OK if the process is gone already
|
71
79
|
end
|
data/spec/support/test_jobs.rb
CHANGED
Binary file
|
@@ -0,0 +1,73 @@
|
|
1
|
+
<style>
|
2
|
+
.progress {
|
3
|
+
background-color: #C8E1ED;
|
4
|
+
}
|
5
|
+
.progress-percentage {
|
6
|
+
margin: 5px;
|
7
|
+
padding-left: 4px;
|
8
|
+
color: #333;
|
9
|
+
text-align: left;
|
10
|
+
text-shadow: 0 0 5px white;
|
11
|
+
font-weight: bold;
|
12
|
+
font-size: 14px;
|
13
|
+
}
|
14
|
+
</style>
|
15
|
+
|
16
|
+
<h3>
|
17
|
+
Job Status: <%= @status.jid %>
|
18
|
+
<span class='label label-<%= @status.label %>'>
|
19
|
+
<%= @status.status %>
|
20
|
+
</span>
|
21
|
+
</h3>
|
22
|
+
|
23
|
+
<div class="progress" style="height: 30px;">
|
24
|
+
<div class="progress-bar" role="progressbar" aria-valuenow="<%= @status.pct_complete.to_i %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= @status.pct_complete.to_i %>%">
|
25
|
+
<div class="progress-percentage">
|
26
|
+
<%= @status.pct_complete.to_i %>%
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div class="panel panel-default">
|
32
|
+
<div class="panel-body">
|
33
|
+
<h4><%= @status.worker %></h4>
|
34
|
+
|
35
|
+
<div class="row">
|
36
|
+
<div class="col-sm-2">
|
37
|
+
<strong>Arguments</strong>
|
38
|
+
</div>
|
39
|
+
<div class="col-sm-10">
|
40
|
+
<p><%= @status.args.empty? ? "<i>none</i>" : @status.args %></p>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="row">
|
45
|
+
<div class="col-sm-2">
|
46
|
+
<strong>Message</strong>
|
47
|
+
</div>
|
48
|
+
<div class="col-sm-10">
|
49
|
+
<p><%= @status.message || "<i>none</i>" %></p>
|
50
|
+
</div>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div class="row">
|
54
|
+
<div class="col-sm-2">
|
55
|
+
<strong>Last Updated</strong>
|
56
|
+
</div>
|
57
|
+
<div class="col-sm-10">
|
58
|
+
<p>
|
59
|
+
<% secs = Time.now.to_i - @status.update_time.to_i %>
|
60
|
+
<% if secs > 0 %>
|
61
|
+
<%= secs %> sec<%= secs == 1 ? '' : 's' %> ago
|
62
|
+
<% else %>
|
63
|
+
Now
|
64
|
+
<% end %>
|
65
|
+
</p>
|
66
|
+
</div>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<a href="<%= root_path %>statuses">
|
72
|
+
<small>← back to all statuses</small>
|
73
|
+
</a>
|
data/web/views/statuses.erb
CHANGED
@@ -4,8 +4,8 @@
|
|
4
4
|
background-color: #C8E1ED;
|
5
5
|
}
|
6
6
|
.bar {
|
7
|
-
background-color: #2897cb;
|
8
|
-
color: white;
|
7
|
+
background-color: #2897cb;
|
8
|
+
color: white;
|
9
9
|
text-shadow: 0 0 0;
|
10
10
|
}
|
11
11
|
.message {
|
@@ -16,21 +16,28 @@
|
|
16
16
|
.header{
|
17
17
|
text-align: center;
|
18
18
|
}
|
19
|
+
.header_update_time{
|
20
|
+
width: 10%;
|
21
|
+
}
|
22
|
+
.header_pct_complete{
|
23
|
+
width: 45%;
|
24
|
+
}
|
25
|
+
|
19
26
|
</style>
|
20
27
|
|
21
28
|
<h3 class="wi">Recent job statuses</h3>
|
22
|
-
<table class="table table-hover table-bordered table-striped table-white">
|
29
|
+
<table class="table table-hover table-bordered table-striped table-white">
|
23
30
|
<tr>
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
<% @headers.each do |h| %>
|
32
|
+
<th class="header <%= h[:class] %> header_<%= h[:id] %>">
|
33
|
+
<a href="<%= h[:url] %>"><%= h[:name] %></a>
|
34
|
+
</th>
|
35
|
+
<% end %>
|
29
36
|
</tr>
|
30
37
|
<% @statuses.each do |container| %>
|
31
38
|
<tr>
|
32
39
|
<td>
|
33
|
-
<div title='<%= container.jid %>'><%= container.worker %></div>
|
40
|
+
<div title='<%= container.jid %>'><a href="<%= root_path %>statuses/<%= container.jid %>"><%= container.worker %></a></div>
|
34
41
|
</td>
|
35
42
|
<td>
|
36
43
|
<div class='args' title='<%= container.jid %>'><%= container.args %></div>
|
@@ -39,9 +46,9 @@
|
|
39
46
|
<div class='label label-<%= container.label %>'><%= container.status %></div>
|
40
47
|
</td>
|
41
48
|
<% secs = Time.now.to_i - container.update_time.to_i %>
|
42
|
-
<td style='text-align: center;'>
|
49
|
+
<td style='text-align: center; white-space: nowrap;' title="<%= Time.at(container.update_time.to_i) %>">
|
43
50
|
<% if secs > 0 %>
|
44
|
-
<%= secs
|
51
|
+
<%= ChronicDuration.output(secs, :weeks => true, :units => 2) %> ago
|
45
52
|
<% else %>
|
46
53
|
Now
|
47
54
|
<% end %>
|
@@ -65,4 +72,4 @@
|
|
65
72
|
<td colspan="6"></td>
|
66
73
|
</tr>
|
67
74
|
<% end %>
|
68
|
-
</table>
|
75
|
+
</table>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-status
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evgeniy Tsvigun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-11-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: chronic_duration
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rack-test
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -95,7 +109,6 @@ files:
|
|
95
109
|
- LICENSE
|
96
110
|
- README.md
|
97
111
|
- Rakefile
|
98
|
-
- gemfiles/Gemfile.sidekiq-2
|
99
112
|
- lib/sidekiq-status.rb
|
100
113
|
- lib/sidekiq-status/client_middleware.rb
|
101
114
|
- lib/sidekiq-status/server_middleware.rb
|
@@ -105,6 +118,7 @@ files:
|
|
105
118
|
- lib/sidekiq-status/web.rb
|
106
119
|
- lib/sidekiq-status/worker.rb
|
107
120
|
- sidekiq-status.gemspec
|
121
|
+
- spec/environment.rb
|
108
122
|
- spec/lib/sidekiq-status/client_middleware_spec.rb
|
109
123
|
- spec/lib/sidekiq-status/server_middleware_spec.rb
|
110
124
|
- spec/lib/sidekiq-status/testing_spec.rb
|
@@ -113,7 +127,10 @@ files:
|
|
113
127
|
- spec/lib/sidekiq-status_spec.rb
|
114
128
|
- spec/spec_helper.rb
|
115
129
|
- spec/support/test_jobs.rb
|
130
|
+
- web/sidekiq-status-single-web.png
|
116
131
|
- web/sidekiq-status-web.png
|
132
|
+
- web/views/status.erb
|
133
|
+
- web/views/status_not_found.erb
|
117
134
|
- web/views/statuses.erb
|
118
135
|
homepage: http://github.com/utgarda/sidekiq-status
|
119
136
|
licenses:
|
@@ -135,11 +152,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
152
|
version: '0'
|
136
153
|
requirements: []
|
137
154
|
rubyforge_project:
|
138
|
-
rubygems_version: 2.
|
155
|
+
rubygems_version: 2.6.13
|
139
156
|
signing_key:
|
140
157
|
specification_version: 4
|
141
158
|
summary: An extension to the sidekiq message processing to track your jobs
|
142
159
|
test_files:
|
160
|
+
- spec/environment.rb
|
143
161
|
- spec/lib/sidekiq-status/client_middleware_spec.rb
|
144
162
|
- spec/lib/sidekiq-status/server_middleware_spec.rb
|
145
163
|
- spec/lib/sidekiq-status/testing_spec.rb
|