rekiq 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +80 -0
- data/Rakefile +2 -0
- data/example/sidekiq.yml +6 -0
- data/example/test_app.rb +30 -0
- data/lib/rekiq/configuration.rb +33 -0
- data/lib/rekiq/exceptions.rb +4 -0
- data/lib/rekiq/job.rb +103 -0
- data/lib/rekiq/middleware/utils.rb +14 -0
- data/lib/rekiq/middleware/work_overseer.rb +58 -0
- data/lib/rekiq/schedule_format_validator.rb +16 -0
- data/lib/rekiq/scheduler.rb +42 -0
- data/lib/rekiq/version.rb +3 -0
- data/lib/rekiq/worker.rb +62 -0
- data/lib/rekiq.rb +22 -0
- data/rekiq.gemspec +31 -0
- data/spec/factories/job.rb +15 -0
- data/spec/rekiq/job_spec.rb +400 -0
- data/spec/rekiq/middleware/utils_spec.rb +48 -0
- data/spec/rekiq/middleware/work_overseer_spec.rb +66 -0
- data/spec/rekiq/scheduler_spec.rb +61 -0
- data/spec/rekiq/worker_spec.rb +73 -0
- data/spec/spec_helper.rb +35 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bc545471fb04e687f4cf1cc9e9289db9060b579c
|
4
|
+
data.tar.gz: 74cc308381099f8711c6a27b16f3875c2d29168f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fae12ce36fd971421f930c9195434b186c968cc8a82cec9c546a332f9551500635ca30f0d83d35426d25ea0b844596a89ef06e48400bef1d5d988cc01b77ab18
|
7
|
+
data.tar.gz: 730dbbba9558c1a9d80e30f2f8707ad102de3faf272e404c9ff65ea155fafd803ae01d99548725645176d1011087ade597e7032d0351913432548bf30cc9c538
|
data/.gitignore
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
example/tmp
|
data/.rspec
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rekiq
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.1.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 junhanamaki
|
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,80 @@
|
|
1
|
+
# Rekiq
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/junhanamaki/rekiq.svg?branch=master)](https://travis-ci.org/junhanamaki/rekiq)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/junhanamaki/rekiq.png)](https://codeclimate.com/github/junhanamaki/rekiq)
|
5
|
+
[![Test Coverage](https://codeclimate.com/github/junhanamaki/rekiq/coverage.png)](https://codeclimate.com/github/junhanamaki/rekiq)
|
6
|
+
[![Dependency Status](https://gemnasium.com/junhanamaki/rekiq.svg)](https://gemnasium.com/junhanamaki/rekiq)
|
7
|
+
|
8
|
+
**Rekiq is a recurring worker extension for
|
9
|
+
[Sidekiq](https://github.com/mperham/sidekiq).**
|
10
|
+
|
11
|
+
Rekiq extends Sidekiq and adds functionality to schedule recurring workers.
|
12
|
+
|
13
|
+
Sidekiq is an amazing gem that allows us delegate time consuming work to a
|
14
|
+
worker, or even to schedule a time for the worker to start. Now wouldn't it be
|
15
|
+
nice if it also allowed us to schedule a worker to do work recurringly? That's
|
16
|
+
what rekiq purposes to do.
|
17
|
+
|
18
|
+
In pratical means, rekiq allows you to schedule a worker to repeat the same
|
19
|
+
work friday at 23:00, for example.
|
20
|
+
|
21
|
+
## Requirements
|
22
|
+
|
23
|
+
Tested with:
|
24
|
+
|
25
|
+
* Ruby version 2.1.1, 2.0.0 and 1.9.3
|
26
|
+
* Sidekiq 3.2.1
|
27
|
+
* ice_cube 0.12.1
|
28
|
+
|
29
|
+
## Installation
|
30
|
+
|
31
|
+
Add this line to your application's Gemfile:
|
32
|
+
|
33
|
+
gem 'rekiq', git: 'https://github.com/junhanamaki/rekiq'
|
34
|
+
|
35
|
+
And then execute:
|
36
|
+
|
37
|
+
$ bundle
|
38
|
+
|
39
|
+
Or compile source by hand, since for now it's not published.
|
40
|
+
|
41
|
+
## Usage
|
42
|
+
|
43
|
+
Require rekiq after sidekiq:
|
44
|
+
|
45
|
+
require 'sidekiq'
|
46
|
+
require 'rekiq'
|
47
|
+
|
48
|
+
We need a 'schedule' object (responsible for returning the time at which the
|
49
|
+
worker should start) which must respond to method next_occurrence and
|
50
|
+
receives one argument of type Time more at [schedule](). For our example we'll use gem
|
51
|
+
[ice_cube](https://github.com/seejohnrun/ice_cube) (don't forget to require it):
|
52
|
+
|
53
|
+
# define worker as normal
|
54
|
+
class ExampleWorker
|
55
|
+
include Sidekiq::Worker
|
56
|
+
|
57
|
+
def perform(arg1, arg2)
|
58
|
+
# Do some work
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# create schedule for worker to repeat every friday at 2am
|
63
|
+
schedule = IceCube::Schedule.new do |s|
|
64
|
+
s.rrule IceCube::Rule.daily.day(:friday).hour_of_day(2)
|
65
|
+
end
|
66
|
+
|
67
|
+
# now just start your worker
|
68
|
+
ExampleWorker.perform_recurringly(schedule, 'argument_1', 'argument_2')
|
69
|
+
|
70
|
+
You can use your own schedule object, configure worker to reschedule before or
|
71
|
+
after work is done, set margin, and much more! So please check
|
72
|
+
[wiki](https://github.com/junhanamaki/rekiq/wiki) for more details.
|
73
|
+
|
74
|
+
## Contributing
|
75
|
+
|
76
|
+
1. Fork it ( https://github.com/[my-github-username]/rekiq/fork )
|
77
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
78
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
79
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
80
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/example/sidekiq.yml
ADDED
data/example/test_app.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# install gem and run with:
|
2
|
+
# bundle exec sidekiq -C example/sidekiq.yml -r ./example/test_app.rb
|
3
|
+
|
4
|
+
require 'ice_cube'
|
5
|
+
require 'sidekiq'
|
6
|
+
require 'rekiq'
|
7
|
+
|
8
|
+
# define sidekiq worker as you normally would
|
9
|
+
class TestWorker1
|
10
|
+
include Sidekiq::Worker
|
11
|
+
|
12
|
+
sidekiq_options queue: "rekiq_test_worker", retry: false
|
13
|
+
|
14
|
+
def perform(arg1, arg2)
|
15
|
+
puts "\n\nhello from TestWorker1, arg1 is #{arg1}, arg2 is #{arg2}" \
|
16
|
+
"scheduled work time was #{scheduled_work_time}\n\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# create ice cube schedule
|
21
|
+
schedule = IceCube::Schedule.new(Time.now) do |s|
|
22
|
+
s.rrule IceCube::Rule.minutely
|
23
|
+
end
|
24
|
+
|
25
|
+
# invoke method
|
26
|
+
TestWorker1.perform_recurringly(
|
27
|
+
schedule,
|
28
|
+
['Rekiq', 'ola', '!!!'],
|
29
|
+
{ 'complex' => { 'hash' => 'woot!' } }
|
30
|
+
)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Rekiq
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :reschedule_post_work, :schedule_expired,
|
4
|
+
:expiration_margin
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
# if work is rescheduled after or before the worker completes
|
8
|
+
self.reschedule_post_work = false
|
9
|
+
|
10
|
+
# if expired works are to be scheduled
|
11
|
+
# an expired work is a work that has a time bellow current_time - margin
|
12
|
+
self.schedule_expired = false
|
13
|
+
|
14
|
+
# indicates the margin after which a work is considered expired
|
15
|
+
# default to 0
|
16
|
+
self.expiration_margin = 0
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
def configure
|
22
|
+
yield configuration
|
23
|
+
end
|
24
|
+
|
25
|
+
def configuration
|
26
|
+
@configuration ||= Configuration.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def reset_configuration
|
30
|
+
@configuration = Configuration.new
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/rekiq/job.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rekiq/schedule_format_validator'
|
3
|
+
|
4
|
+
module Rekiq
|
5
|
+
class Job
|
6
|
+
include ActiveModel::Validations
|
7
|
+
include ActiveModel::Validations::Callbacks
|
8
|
+
|
9
|
+
attr_accessor :schedule, :shift, :reschedule_post_work, :schedule_expired,
|
10
|
+
:expiration_margin
|
11
|
+
|
12
|
+
validates :schedule, 'rekiq::_schedule_format' => true
|
13
|
+
validates :shift, numericality: true
|
14
|
+
validates :reschedule_post_work, :schedule_expired,
|
15
|
+
inclusion: { in: [true, false], allow_nil: true }
|
16
|
+
validates :expiration_margin,
|
17
|
+
numericality: { greater_than_or_equal_to: 0, allow_nil: true }
|
18
|
+
|
19
|
+
def self.from_short_key_hash(hash)
|
20
|
+
hash['schedule'] = YAML::load(hash['sch'])
|
21
|
+
hash['shift'] = hash['sft']
|
22
|
+
hash['reschedule_post_work'] = hash['rpw']
|
23
|
+
hash['schedule_expired'] = hash['se']
|
24
|
+
hash['expiration_margin'] = hash['em']
|
25
|
+
|
26
|
+
new(hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize(attributes = {})
|
30
|
+
self.schedule = attributes['schedule']
|
31
|
+
self.shift = attributes['shift'] || 0
|
32
|
+
self.reschedule_post_work = attributes['reschedule_post_work']
|
33
|
+
self.schedule_expired = attributes['schedule_expired']
|
34
|
+
self.expiration_margin = attributes['expiration_margin']
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_short_key_hash
|
38
|
+
{
|
39
|
+
'sch' => YAML::dump(schedule),
|
40
|
+
'sft' => shift,
|
41
|
+
'rpw' => reschedule_post_work,
|
42
|
+
'se' => schedule_expired,
|
43
|
+
'em' => expiration_margin
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def next_work_time(from = Time.now)
|
48
|
+
shifted_from = shift > 0 ? from - shift : from
|
49
|
+
|
50
|
+
search_next_work_time(shifted_from)
|
51
|
+
end
|
52
|
+
|
53
|
+
def next_work_time_from_work_time(from)
|
54
|
+
shifted_from = from - shift
|
55
|
+
|
56
|
+
search_next_work_time(shifted_from)
|
57
|
+
end
|
58
|
+
|
59
|
+
def reschedule_post_work?
|
60
|
+
unless reschedule_post_work.nil?
|
61
|
+
reschedule_post_work
|
62
|
+
else
|
63
|
+
Rekiq.configuration.reschedule_post_work
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
|
69
|
+
def search_next_work_time(from)
|
70
|
+
if schedule_expired?
|
71
|
+
from = schedule.next_occurrence(from)
|
72
|
+
work_time = from.nil? ? nil : from + shift
|
73
|
+
else
|
74
|
+
begin
|
75
|
+
from = schedule.next_occurrence(from)
|
76
|
+
work_time = from.nil? ? nil : from + shift
|
77
|
+
end until work_time.nil? || work_time > expiration_time
|
78
|
+
end
|
79
|
+
|
80
|
+
work_time
|
81
|
+
end
|
82
|
+
|
83
|
+
def schedule_expired?
|
84
|
+
unless schedule_expired.nil?
|
85
|
+
schedule_expired
|
86
|
+
else
|
87
|
+
Rekiq.configuration.schedule_expired
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def expiration_margin_val
|
92
|
+
unless expiration_margin.nil?
|
93
|
+
expiration_margin
|
94
|
+
else
|
95
|
+
Rekiq.configuration.expiration_margin
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def expiration_time
|
100
|
+
Time.now - expiration_margin_val
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'sidekiq'
|
2
|
+
require 'sidekiq/util'
|
3
|
+
require 'rekiq/configuration'
|
4
|
+
require 'rekiq/job'
|
5
|
+
require 'rekiq/scheduler'
|
6
|
+
|
7
|
+
module Rekiq
|
8
|
+
module Middleware
|
9
|
+
class WorkOverseer
|
10
|
+
include ::Sidekiq::Util
|
11
|
+
|
12
|
+
attr_accessor :worker_name, :queue, :args, :job, :addon,
|
13
|
+
:scheduled_work_time
|
14
|
+
|
15
|
+
def call(worker, msg, queue)
|
16
|
+
return yield unless msg['rq:job']
|
17
|
+
|
18
|
+
self.worker_name = worker.class.name
|
19
|
+
self.queue = queue
|
20
|
+
self.args = msg['args']
|
21
|
+
self.job = Job.from_short_key_hash(msg['rq:job'])
|
22
|
+
self.addon = msg['rq:addon']
|
23
|
+
|
24
|
+
if msg['retry_count'].nil?
|
25
|
+
self.scheduled_work_time = Time.at(msg['rq:at'].to_f)
|
26
|
+
reschedule_post_work = job.reschedule_post_work?
|
27
|
+
|
28
|
+
if reschedule_post_work
|
29
|
+
begin
|
30
|
+
yield
|
31
|
+
ensure
|
32
|
+
reschedule
|
33
|
+
end
|
34
|
+
else
|
35
|
+
reschedule
|
36
|
+
yield
|
37
|
+
end
|
38
|
+
else
|
39
|
+
yield
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def reschedule
|
44
|
+
jid, work_time =
|
45
|
+
Rekiq::Scheduler
|
46
|
+
.new(worker_name, queue, args, job, addon)
|
47
|
+
.schedule_from_work_time(scheduled_work_time)
|
48
|
+
|
49
|
+
unless jid.nil?
|
50
|
+
logger.info "recurring work for #{worker_name} scheduled for " \
|
51
|
+
"#{work_time} with jid #{jid}"
|
52
|
+
else
|
53
|
+
logger.info 'recurrence terminated, job terminated'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module Rekiq
|
4
|
+
class ScheduleFormatValidator < ActiveModel::EachValidator
|
5
|
+
def validate_each(record, attribute, value)
|
6
|
+
unless value.respond_to?(:next_occurrence) and
|
7
|
+
value.method(:next_occurrence).arity.abs > 0
|
8
|
+
record.errors[attribute] <<
|
9
|
+
"invalid value for #{attribute}, value must be an object that " \
|
10
|
+
'responds to next_occurrence, and that receives at least one ' \
|
11
|
+
'argument of type Time, representing Time from which to calculate ' \
|
12
|
+
'next occurrence time'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Rekiq
|
2
|
+
class Scheduler
|
3
|
+
attr_accessor :worker_name, :queue, :args, :job, :addon, :work_time
|
4
|
+
|
5
|
+
def initialize(worker_name, queue, args, job, addon)
|
6
|
+
self.worker_name = worker_name
|
7
|
+
self.queue = queue
|
8
|
+
self.args = args
|
9
|
+
self.job = job
|
10
|
+
self.addon = addon
|
11
|
+
end
|
12
|
+
|
13
|
+
def schedule(from = Time.now)
|
14
|
+
self.work_time = job.next_work_time(from)
|
15
|
+
|
16
|
+
work_time.nil? ? nil : [schedule_work, work_time]
|
17
|
+
end
|
18
|
+
|
19
|
+
def schedule_from_work_time(from)
|
20
|
+
self.work_time = job.next_work_time_from_work_time(from)
|
21
|
+
|
22
|
+
work_time.nil? ? nil : [schedule_work, work_time]
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def schedule_work
|
28
|
+
client_args = {
|
29
|
+
'at' => work_time.to_f,
|
30
|
+
'queue' => queue,
|
31
|
+
'class' => worker_name,
|
32
|
+
'args' => args,
|
33
|
+
'rq:job' => job.to_short_key_hash,
|
34
|
+
'rq:at' => work_time.to_f
|
35
|
+
}.tap do |hash|
|
36
|
+
hash['rq:addon'] = addon unless addon.nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
Sidekiq::Client.push(client_args)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/rekiq/worker.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rekiq/exceptions'
|
2
|
+
require 'rekiq/job'
|
3
|
+
require 'rekiq/scheduler'
|
4
|
+
|
5
|
+
module Rekiq
|
6
|
+
module Worker
|
7
|
+
class Configuration
|
8
|
+
attr_accessor :shift, :reschedule_post_work, :schedule_expired,
|
9
|
+
:expiration_margin, :addon
|
10
|
+
|
11
|
+
def append_to_msg(addon)
|
12
|
+
self.addon = addon
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ClassMethods
|
17
|
+
def perform_recurringly(schedule, *args)
|
18
|
+
config = Configuration.new
|
19
|
+
yield config if block_given?
|
20
|
+
|
21
|
+
job =
|
22
|
+
Rekiq::Job
|
23
|
+
.new 'schedule' => schedule,
|
24
|
+
'shift' => config.shift,
|
25
|
+
'reschedule_post_work' => config.reschedule_post_work,
|
26
|
+
'schedule_expired' => config.schedule_expired,
|
27
|
+
'expiration_margin' => config.expiration_margin
|
28
|
+
|
29
|
+
queue = get_sidekiq_options['queue']
|
30
|
+
|
31
|
+
jid, work_time =
|
32
|
+
Rekiq::Scheduler
|
33
|
+
.new(name, queue, args, job, config.addon)
|
34
|
+
.schedule
|
35
|
+
|
36
|
+
return if jid.nil?
|
37
|
+
|
38
|
+
::Sidekiq.logger.info "recurring work for #{name} scheduled for " \
|
39
|
+
"#{work_time} with jid #{jid}"
|
40
|
+
|
41
|
+
jid
|
42
|
+
rescue StandardError => e
|
43
|
+
raise Rekiq::StandardError,
|
44
|
+
'unable to schedule worker',
|
45
|
+
e.backtrace
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module Sidekiq
|
52
|
+
module Worker
|
53
|
+
attr_accessor :scheduled_work_time
|
54
|
+
|
55
|
+
original_included_method = method(:included)
|
56
|
+
|
57
|
+
define_singleton_method :included do |base|
|
58
|
+
original_included_method.call(base)
|
59
|
+
base.extend(Rekiq::Worker::ClassMethods)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/rekiq.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rekiq/version'
|
2
|
+
require 'rekiq/exceptions'
|
3
|
+
|
4
|
+
unless defined?(Sidekiq)
|
5
|
+
raise Rekiq::SidekiqNotLoaded,
|
6
|
+
'sidekiq must be required before requiring rekiq'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rekiq/middleware/work_overseer'
|
10
|
+
require 'rekiq/middleware/utils'
|
11
|
+
require 'rekiq/worker'
|
12
|
+
|
13
|
+
module Rekiq
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
Sidekiq.configure_server do |config|
|
18
|
+
config.server_middleware do |chain|
|
19
|
+
chain.add Rekiq::Middleware::Utils
|
20
|
+
chain.add Rekiq::Middleware::WorkOverseer
|
21
|
+
end
|
22
|
+
end
|
data/rekiq.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rekiq/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rekiq"
|
8
|
+
spec.version = Rekiq::VERSION
|
9
|
+
spec.authors = ["junhanamaki"]
|
10
|
+
spec.email = ["jun.hanamaki@gmail.com"]
|
11
|
+
spec.summary = %q{recurring worker extension for sidekiq}
|
12
|
+
spec.description = %q{}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
22
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
23
|
+
spec.add_development_dependency 'simplecov', '~> 0.9'
|
24
|
+
spec.add_development_dependency 'codeclimate-test-reporter', '~> 0.3'
|
25
|
+
spec.add_development_dependency 'factory_girl', '~> 4.4'
|
26
|
+
spec.add_development_dependency 'jazz_hands', '~> 0.5'
|
27
|
+
spec.add_development_dependency 'ice_cube', '~> 0.12'
|
28
|
+
spec.add_development_dependency 'sidekiq', '~> 3.2'
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'activemodel', '~> 4.1'
|
31
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'ice_cube'
|
2
|
+
|
3
|
+
FactoryGirl.define do
|
4
|
+
factory :job, class: Rekiq::Job do
|
5
|
+
shift 0
|
6
|
+
schedule { IceCube::Schedule.new(Time.now + 3600) }
|
7
|
+
|
8
|
+
trait :randomized_attributes do
|
9
|
+
shift { [*0..100].sample }
|
10
|
+
reschedule_post_work { [nil, false, true].sample }
|
11
|
+
schedule_expired { [nil, false, true].sample }
|
12
|
+
expiration_margin { [*0..100].sample }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|