sidekiq-status 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.rspec +3 -0
- data/LICENSE +22 -0
- data/README.md +61 -0
- data/Rakefile +9 -0
- data/lib/sidekiq-status/client_middleware.rb +16 -0
- data/lib/sidekiq-status/server_middleware.rb +46 -0
- data/lib/sidekiq-status/storage.rb +31 -0
- data/lib/sidekiq-status/version.rb +5 -0
- data/lib/sidekiq-status/worker.rb +47 -0
- data/lib/sidekiq-status.rb +20 -0
- data/sidekiq-status.gemspec +19 -0
- data/spec/lib/sidekiq-status/client_middleware_spec.rb +25 -0
- data/spec/lib/sidekiq-status/server_middleware_spec.rb +43 -0
- data/spec/lib/sidekiq-status/worker_spec.rb +13 -0
- data/spec/lib/sidekiq-status_spec.rb +55 -0
- data/spec/spec_helper.rb +66 -0
- data/spec/support/test_jobs.rb +52 -0
- metadata +103 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Evgeniy Tsvigun
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Sidekiq::Status
|
2
|
+
|
3
|
+
An extension to [Sidekiq](http://github.com/mperham/sidekiq) message processing to track your jobs. Inspired
|
4
|
+
by [resque-status](http://github.com/quirkey/resque-status) and mostly copying its features, using Sidekiq's middleware.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
gem install sidekiq-status
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
Configure your middleware chains, lookup [Middleware usage](https://github.com/mperham/sidekiq/wiki/Middleware)
|
13
|
+
on Sidekiq wiki for more info.
|
14
|
+
|
15
|
+
``` ruby
|
16
|
+
require 'sidekiq'
|
17
|
+
require 'sidekiq-status'
|
18
|
+
|
19
|
+
Sidekiq.configure_client do |config|
|
20
|
+
config.client_middleware do |chain|
|
21
|
+
chain.add Sidekiq::Status::ClientMiddleware
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Sidekiq.configure_server do |config|
|
26
|
+
config.server_middleware do |chain|
|
27
|
+
chain.add Sidekiq::Status::ServerMiddleware
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
When defining those jobs you want to track later, include one more module. Jobs defined without Sidekiq::Status::Worker
|
33
|
+
will be processed as usual.
|
34
|
+
|
35
|
+
``` ruby
|
36
|
+
class MyJob
|
37
|
+
include Sidekiq::Worker
|
38
|
+
include Sidekiq::Status::Worker
|
39
|
+
|
40
|
+
def perform(*args)
|
41
|
+
# your code goes here
|
42
|
+
end
|
43
|
+
end
|
44
|
+
```
|
45
|
+
|
46
|
+
Query for job status any time later:
|
47
|
+
|
48
|
+
``` ruby
|
49
|
+
job_id = MyJob.perform_async(*args)
|
50
|
+
# "queued", "working", "complete" or "failed" , nil after expiry (30 minutes)
|
51
|
+
status = Sidekiq::Status::get(job_id)
|
52
|
+
```
|
53
|
+
|
54
|
+
### Features coming
|
55
|
+
* Progress tracking, messages from running jobs
|
56
|
+
* Stopping jobs by id
|
57
|
+
* Minimal web UI
|
58
|
+
|
59
|
+
## License
|
60
|
+
MIT License , see LICENSE for more details.
|
61
|
+
© 2012 Evgeniy Tsvigun
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Sidekiq::Status
|
2
|
+
# Should be in the client middleware chain
|
3
|
+
class ClientMiddleware
|
4
|
+
include Storage
|
5
|
+
# Uses the first argument as id and puts :queued status in the job's Redis hash
|
6
|
+
# @param [Class] worker_class if includes Sidekiq::Status::Worker, the job gets processed with the plugin
|
7
|
+
# @param [Array] msg job arguments, the firs one becomes the id
|
8
|
+
# @param [String] queue the queue's name
|
9
|
+
def call(worker_class, msg, queue)
|
10
|
+
if worker_class.include? Worker
|
11
|
+
store_for_id(msg['args'][0], :status => :queued)
|
12
|
+
end
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Sidekiq::Status
|
2
|
+
# Should be in the server middleware chain
|
3
|
+
class ServerMiddleware
|
4
|
+
# Parameterized initialization, use it when adding middleware to server chain
|
5
|
+
# chain.add Sidekiq::Status::ServerMiddleware, :expiration => 60 * 5
|
6
|
+
# @param [Hash] opts middleware initialization options
|
7
|
+
# @option opts [Fixnum] :expiration ttl for complete jobs
|
8
|
+
def initialize(opts = {:expiration => 30 * 60})
|
9
|
+
@expiration = opts[:expiration]
|
10
|
+
end
|
11
|
+
|
12
|
+
# Takes out the first job argument to use as id
|
13
|
+
# puts :working status into Redis hash
|
14
|
+
# initializes worker instance with id
|
15
|
+
#
|
16
|
+
# Exception handler sets :failed status, re-inserts worker it to job args and re-throws the exception
|
17
|
+
# Worker::Stopped exception type are processed separately - :stopped status is set, no re-throwing
|
18
|
+
#
|
19
|
+
# @param [Worker] worker worker instance, processed here if its class includes Status::Worker
|
20
|
+
# @param [Array] msg job args, first of them used as job id, should have uuid format
|
21
|
+
# @param [String] queue queue name
|
22
|
+
def call(worker, msg, queue)
|
23
|
+
if worker.is_a? Worker
|
24
|
+
worker.id = msg['args'].shift
|
25
|
+
unless worker.id.is_a?(String) && UUID_REGEXP.match(worker.id)
|
26
|
+
raise ArgumentError, "First job argument for a #{worker.class.name} should have uuid format"
|
27
|
+
end
|
28
|
+
worker.store 'status' => 'working'
|
29
|
+
yield
|
30
|
+
worker.store 'status' => 'complete'
|
31
|
+
else
|
32
|
+
yield
|
33
|
+
end
|
34
|
+
rescue Worker::Stopped
|
35
|
+
worker.store 'status' => 'stopped'
|
36
|
+
rescue
|
37
|
+
if worker.is_a? Worker
|
38
|
+
worker.store 'status' => 'failed'
|
39
|
+
msg['args'].unshift worker.id
|
40
|
+
end
|
41
|
+
raise
|
42
|
+
ensure
|
43
|
+
Sidekiq.redis { |conn| conn.expire worker.id, @expiration } if worker.is_a? Worker
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Sidekiq::Status::Storage
|
2
|
+
RESERVED_FIELDS=%w(status stop update_time).freeze
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
# Stores multiple values into a job's status hash,
|
7
|
+
# sets last update time
|
8
|
+
# @param [String] id job id
|
9
|
+
# @param [Hash] status_updates updated values
|
10
|
+
# @return [String] Redis operation status code
|
11
|
+
def store_for_id(id, status_updates)
|
12
|
+
Sidekiq.redis do |conn|
|
13
|
+
answers = conn.multi do
|
14
|
+
conn.hmset id, 'update_time', Time.now.to_i, *(status_updates.to_a.flatten)
|
15
|
+
conn.expire id, Sidekiq::Status::DEFAULT_EXPIRY
|
16
|
+
conn.publish "status_updates", id
|
17
|
+
end
|
18
|
+
answers[0]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Gets a single valued from job status hash
|
23
|
+
# @param [String] id job id
|
24
|
+
# @param [String] Symbol field fetched field name
|
25
|
+
# @return [String] Redis operation status code
|
26
|
+
def read_field_for_id(uuid, field)
|
27
|
+
Sidekiq.redis do |conn|
|
28
|
+
conn.hmget(uuid, field)[0]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "active_support"
|
2
|
+
|
3
|
+
module Sidekiq::Status::Worker
|
4
|
+
include Sidekiq::Status::Storage
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
# Adding ID generation to .perform_async
|
8
|
+
module ClassMethods
|
9
|
+
# :nodoc:
|
10
|
+
def self.extended(base)
|
11
|
+
class << base
|
12
|
+
alias_method_chain :perform_async, :uuid
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Add an id to job arguments
|
17
|
+
def perform_async_with_uuid(*args)
|
18
|
+
id = SecureRandom.uuid
|
19
|
+
args.unshift id
|
20
|
+
perform_async_without_uuid(*args)
|
21
|
+
id
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Stopped < StandardError
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :id
|
29
|
+
|
30
|
+
# Worker id initialization
|
31
|
+
# @param [String] id id generated on client-side
|
32
|
+
# @raise [RuntimeError] raised in case of second id initialization attempt
|
33
|
+
# @return [String] id
|
34
|
+
def id=(id)
|
35
|
+
raise RuntimeError("Worker ID is already set : #@id") if @id
|
36
|
+
@id=id
|
37
|
+
end
|
38
|
+
|
39
|
+
# Stores multiple values into a job's status hash,
|
40
|
+
# sets last update time
|
41
|
+
# @param [Hash] status_updates updated values
|
42
|
+
# @return [String] Redis operation status code
|
43
|
+
def store(hash)
|
44
|
+
store_for_id(@id, hash)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "sidekiq-status/version"
|
2
|
+
require 'sidekiq-status/storage'
|
3
|
+
require 'sidekiq-status/worker'
|
4
|
+
require 'sidekiq-status/client_middleware'
|
5
|
+
require 'sidekiq-status/server_middleware'
|
6
|
+
|
7
|
+
module Sidekiq
|
8
|
+
module Status
|
9
|
+
extend Storage
|
10
|
+
DEFAULT_EXPIRY = 60 * 30
|
11
|
+
UUID_REGEXP = /[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}/
|
12
|
+
|
13
|
+
# Job status by id
|
14
|
+
# @param [String] id job id returned by async_perform
|
15
|
+
# @return [String] job status, possible values: "queued" , "working" , "complete"
|
16
|
+
def self.get(id)
|
17
|
+
read_field_for_id(id, :status)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sidekiq-status/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ['Evgeniy Tsvigun']
|
6
|
+
gem.email = ['utgarda@gmail.com']
|
7
|
+
gem.summary = 'An extension to the sidekiq message processing to track your jobs'
|
8
|
+
gem.homepage = 'http://github.com/utgarda/sidekiq-status'
|
9
|
+
gem.license = 'MIT'
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
13
|
+
gem.name = 'sidekiq-status'
|
14
|
+
gem.require_paths = ['lib']
|
15
|
+
gem.version = Sidekiq::Status::VERSION
|
16
|
+
|
17
|
+
gem.add_dependency 'sidekiq', '~> 2.2'
|
18
|
+
gem.add_development_dependency 'rspec'
|
19
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sidekiq::Status::ClientMiddleware do
|
4
|
+
|
5
|
+
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
6
|
+
let!(:job_id) { SecureRandom.uuid }
|
7
|
+
|
8
|
+
# Clean Redis before each test
|
9
|
+
before { redis.flushall }
|
10
|
+
|
11
|
+
describe "#call" do
|
12
|
+
it "sets queued status" do
|
13
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
14
|
+
StubJob.perform_async(:arg1 => 'val1').should == job_id
|
15
|
+
redis.hget(job_id, :status).should == 'queued'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "sets status hash ttl" do
|
19
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
20
|
+
StubJob.perform_async(:arg1 => 'val1').should == job_id
|
21
|
+
(1..Sidekiq::Status::DEFAULT_EXPIRY).should cover redis.ttl(job_id)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sidekiq::Status::ServerMiddleware do
|
4
|
+
|
5
|
+
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
6
|
+
let!(:job_id) { SecureRandom.uuid }
|
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
|
+
describe "#call" do
|
14
|
+
it "sets working/complete status" do
|
15
|
+
thread = confirmations_thread 4, "status_updates", "job_messages_#{job_id}"
|
16
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
17
|
+
start_server do
|
18
|
+
ConfirmationJob.perform_async(:arg1 => 'val1').should == job_id
|
19
|
+
thread.value.should == [job_id, job_id,
|
20
|
+
"while in #perform, status = working",
|
21
|
+
job_id]
|
22
|
+
end
|
23
|
+
redis.hget(job_id, :status).should == 'complete'
|
24
|
+
end
|
25
|
+
|
26
|
+
it "sets failed status" do
|
27
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
28
|
+
start_server do
|
29
|
+
capture_status_updates(3) {
|
30
|
+
FailingJob.perform_async.should == job_id
|
31
|
+
}.should == [job_id]*3
|
32
|
+
end
|
33
|
+
redis.hget(job_id, :status).should == 'failed'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "sets status hash ttl" do
|
37
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
38
|
+
StubJob.perform_async(:arg1 => 'val1').should == job_id
|
39
|
+
(1..Sidekiq::Status::DEFAULT_EXPIRY).should cover redis.ttl(job_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sidekiq::Status::Worker do
|
4
|
+
|
5
|
+
let!(:job_id) { SecureRandom.uuid }
|
6
|
+
|
7
|
+
describe ".perform_async" do
|
8
|
+
it "generates and returns job id" do
|
9
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
10
|
+
StubJob.perform_async().should == job_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Sidekiq::Status do
|
4
|
+
|
5
|
+
let!(:redis) { Sidekiq.redis { |conn| conn } }
|
6
|
+
let!(:job_id) { SecureRandom.uuid }
|
7
|
+
let!(:job_id_1) { SecureRandom.uuid }
|
8
|
+
|
9
|
+
# Clean Redis before each test
|
10
|
+
# Seems like flushall has no effect on recently published messages,
|
11
|
+
# so we should wait till they expire
|
12
|
+
before { redis.flushall; sleep 0.1 }
|
13
|
+
|
14
|
+
describe ".get" do
|
15
|
+
it "gets job status by id" do
|
16
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
17
|
+
|
18
|
+
start_server do
|
19
|
+
capture_status_updates(2) {
|
20
|
+
LongJob.perform_async(1).should == job_id
|
21
|
+
}.should == [job_id]*2
|
22
|
+
Sidekiq::Status.get(job_id).should == "working"
|
23
|
+
end
|
24
|
+
Sidekiq::Status.get(job_id).should == 'complete'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "keeps normal Sidekiq functionality" do
|
29
|
+
it "does jobs with and without status processing" do
|
30
|
+
SecureRandom.should_receive(:uuid).twice.and_return(job_id, job_id_1)
|
31
|
+
start_server do
|
32
|
+
capture_status_updates(6) {
|
33
|
+
StubJob.perform_async.should == job_id
|
34
|
+
NoStatusConfirmationJob.perform_async(1)
|
35
|
+
StubJob.perform_async.should == job_id_1
|
36
|
+
NoStatusConfirmationJob.perform_async(2)
|
37
|
+
}.should =~ [job_id, job_id_1] * 3
|
38
|
+
end
|
39
|
+
redis.mget('NoStatusConfirmationJob_1', 'NoStatusConfirmationJob_2').should == %w(done)*2
|
40
|
+
Sidekiq::Status.get(job_id).should == 'complete'
|
41
|
+
Sidekiq::Status.get(job_id_1).should == 'complete'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "retries failed jobs" do
|
45
|
+
SecureRandom.should_receive(:uuid).once.and_return(job_id)
|
46
|
+
start_server do
|
47
|
+
capture_status_updates(5) {
|
48
|
+
RetriedJob.perform_async().should == job_id
|
49
|
+
}.should == [job_id] * 5
|
50
|
+
end
|
51
|
+
Sidekiq::Status.get(job_id).should == 'complete'
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require "rspec"
|
2
|
+
|
3
|
+
require 'sidekiq'
|
4
|
+
require 'sidekiq-status'
|
5
|
+
|
6
|
+
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
8
|
+
|
9
|
+
Sidekiq.configure_client do |config|
|
10
|
+
config.client_middleware do |chain|
|
11
|
+
chain.add Sidekiq::Status::ClientMiddleware
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def confirmations_thread(messages_limit, *channels)
|
16
|
+
parent = Thread.current
|
17
|
+
thread = Thread.new {
|
18
|
+
confirmations = []
|
19
|
+
Sidekiq.redis do |conn|
|
20
|
+
conn.subscribe *channels do |on|
|
21
|
+
on.subscribe do |ch, subscriptions|
|
22
|
+
if subscriptions == channels.size
|
23
|
+
sleep 0.1 while parent.status != "sleep"
|
24
|
+
parent.run
|
25
|
+
end
|
26
|
+
end
|
27
|
+
on.message do |ch, msg|
|
28
|
+
confirmations << msg
|
29
|
+
conn.unsubscribe if confirmations.length >= messages_limit
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
confirmations
|
34
|
+
}
|
35
|
+
Thread.stop
|
36
|
+
yield if block_given?
|
37
|
+
thread
|
38
|
+
end
|
39
|
+
|
40
|
+
def capture_status_updates(n, &block)
|
41
|
+
confirmations_thread(n, "status_updates", &block).value
|
42
|
+
end
|
43
|
+
|
44
|
+
def start_server()
|
45
|
+
pid = Process.fork do
|
46
|
+
$stdout.reopen File::NULL, 'w'
|
47
|
+
$stderr.reopen File::NULL, 'w'
|
48
|
+
require 'sidekiq/cli'
|
49
|
+
Sidekiq.options[:queues] << 'default'
|
50
|
+
Sidekiq.configure_server do |config|
|
51
|
+
config.redis = {:url => 'redis://localhost:6379'}
|
52
|
+
config.server_middleware do |chain|
|
53
|
+
chain.add Sidekiq::Status::ServerMiddleware
|
54
|
+
end
|
55
|
+
end
|
56
|
+
Sidekiq::CLI.instance.run
|
57
|
+
end
|
58
|
+
|
59
|
+
yield
|
60
|
+
|
61
|
+
sleep 0.1
|
62
|
+
Process.kill 'TERM', pid
|
63
|
+
Timeout::timeout(10) { Process.wait pid } rescue Timeout::Error
|
64
|
+
ensure
|
65
|
+
Process.kill 'KILL', pid rescue "OK" # it's OK if the process is gone already
|
66
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
class StubJob
|
2
|
+
include Sidekiq::Worker
|
3
|
+
include Sidekiq::Status::Worker
|
4
|
+
|
5
|
+
sidekiq_options 'retry' => 'false'
|
6
|
+
|
7
|
+
def perform(*args)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class LongJob < StubJob
|
12
|
+
def perform(*args)
|
13
|
+
sleep args[0] || 1
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class ConfirmationJob < StubJob
|
18
|
+
def perform(*args)
|
19
|
+
Sidekiq.redis do |conn|
|
20
|
+
conn.publish "job_messages_#{id}", "while in #perform, status = #{conn.hget id, :status}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class NoStatusConfirmationJob
|
26
|
+
include Sidekiq::Worker
|
27
|
+
def perform(id)
|
28
|
+
Sidekiq.redis do |conn|
|
29
|
+
conn.set "NoStatusConfirmationJob_#{id}", "done"
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class FailingJob < StubJob
|
36
|
+
def perform
|
37
|
+
raise StandardError
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class RetriedJob < StubJob
|
42
|
+
sidekiq_options 'retry' => 'true'
|
43
|
+
def perform()
|
44
|
+
Sidekiq.redis do |conn|
|
45
|
+
key = "RetriedJob_#{id}"
|
46
|
+
unless conn.exists key
|
47
|
+
conn.set key, 'tried'
|
48
|
+
raise StandardError
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sidekiq-status
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Evgeniy Tsvigun
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sidekiq
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.2'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.2'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description:
|
47
|
+
email:
|
48
|
+
- utgarda@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- .rspec
|
55
|
+
- LICENSE
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/sidekiq-status.rb
|
59
|
+
- lib/sidekiq-status/client_middleware.rb
|
60
|
+
- lib/sidekiq-status/server_middleware.rb
|
61
|
+
- lib/sidekiq-status/storage.rb
|
62
|
+
- lib/sidekiq-status/version.rb
|
63
|
+
- lib/sidekiq-status/worker.rb
|
64
|
+
- sidekiq-status.gemspec
|
65
|
+
- spec/lib/sidekiq-status/client_middleware_spec.rb
|
66
|
+
- spec/lib/sidekiq-status/server_middleware_spec.rb
|
67
|
+
- spec/lib/sidekiq-status/worker_spec.rb
|
68
|
+
- spec/lib/sidekiq-status_spec.rb
|
69
|
+
- spec/spec_helper.rb
|
70
|
+
- spec/support/test_jobs.rb
|
71
|
+
homepage: http://github.com/utgarda/sidekiq-status
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
require_paths:
|
77
|
+
- lib
|
78
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 1.8.23
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: An extension to the sidekiq message processing to track your jobs
|
96
|
+
test_files:
|
97
|
+
- spec/lib/sidekiq-status/client_middleware_spec.rb
|
98
|
+
- spec/lib/sidekiq-status/server_middleware_spec.rb
|
99
|
+
- spec/lib/sidekiq-status/worker_spec.rb
|
100
|
+
- spec/lib/sidekiq-status_spec.rb
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- spec/support/test_jobs.rb
|
103
|
+
has_rdoc:
|