rekiq 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|
+
[](https://travis-ci.org/junhanamaki/rekiq)
|
4
|
+
[](https://codeclimate.com/github/junhanamaki/rekiq)
|
5
|
+
[](https://codeclimate.com/github/junhanamaki/rekiq)
|
6
|
+
[](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
|