docket 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +19 -0
- data/.travis.yml +6 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/docket.gemspec +28 -0
- data/example.db +0 -0
- data/lib/docket/repeater.rb +53 -0
- data/lib/docket/robin_list.rb +33 -0
- data/lib/docket/round_robin.rb +38 -0
- data/lib/docket/storage.rb +56 -0
- data/lib/docket/version.rb +3 -0
- data/lib/docket.rb +9 -0
- data/spec/repeater_spec.rb +96 -0
- data/spec/round_robin_spec.rb +47 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/storage_spec.rb +75 -0
- metadata +170 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Hubert Liu
|
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,29 @@
|
|
1
|
+
# docket
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'docket'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install docket
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/docket/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/docket.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'docket/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "docket"
|
8
|
+
spec.version = Docket::VERSION
|
9
|
+
spec.authors = ["Hubert Liu"]
|
10
|
+
spec.email = ["hubert.liu@rigor.com"]
|
11
|
+
spec.summary = %q{Helps schedule jobs}
|
12
|
+
spec.description = %q{Helps schedule jobs}
|
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.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "pry"
|
25
|
+
|
26
|
+
spec.add_dependency 'daybreak'
|
27
|
+
spec.add_dependency 'rufus-scheduler'
|
28
|
+
end
|
data/example.db
ADDED
Binary file
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rufus-scheduler'
|
2
|
+
|
3
|
+
module Docket
|
4
|
+
class Repeater
|
5
|
+
|
6
|
+
attr_accessor :frequencies, :perform_action, :perform_on,
|
7
|
+
:scheduler, :scheduler_action, :scheduler_set_callback
|
8
|
+
attr_reader :storage, :repeat
|
9
|
+
|
10
|
+
def initialize args={}
|
11
|
+
@frequencies = args[:frequencies]
|
12
|
+
@perform_action = args[:perform_action]
|
13
|
+
@perform_on = args[:perform_on]
|
14
|
+
@scheduler = args[:scheduler] || Rufus::Scheduler.new
|
15
|
+
@scheduler_action = args[:scheduler_action]
|
16
|
+
@scheduler_set_callback = args[:scheduler_set_callback] || lambda {|scheduler|}
|
17
|
+
@storage = args[:storage] || Docket::Storage.new('/tmp/docket.rb')
|
18
|
+
@repeat = args[:repeat]
|
19
|
+
end
|
20
|
+
|
21
|
+
def repeated_items
|
22
|
+
frequencies.collect { |frequency| items_for frequency }.compact.flatten
|
23
|
+
end
|
24
|
+
|
25
|
+
def items_for frequency
|
26
|
+
Array(storage.read(frequency))
|
27
|
+
end
|
28
|
+
|
29
|
+
def set
|
30
|
+
frequencies.each do |frequency|
|
31
|
+
if scheduler_action
|
32
|
+
scheduler_action.call(self, frequency)
|
33
|
+
else
|
34
|
+
scheduler.every(frequency, :times => repeat) do
|
35
|
+
items_for(frequency).each { |key| perform_on.perform(key, perform_action) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
scheduler_set_callback.call(scheduler)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stop force=false
|
45
|
+
if force
|
46
|
+
scheduler.shutdown(:kill)
|
47
|
+
else
|
48
|
+
scheduler.shutdown(:wait)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# adapted from https://github.com/bangthetable/CircularList
|
2
|
+
|
3
|
+
module Docket
|
4
|
+
class RobinList
|
5
|
+
def initialize(array)
|
6
|
+
@array = array
|
7
|
+
end
|
8
|
+
|
9
|
+
def size
|
10
|
+
@array.size
|
11
|
+
end
|
12
|
+
|
13
|
+
def list
|
14
|
+
@array
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch_previous(index=0)
|
18
|
+
index.nil? ? nil : @array.unshift(@array.pop)[index]
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch_next(index=0)
|
22
|
+
index.nil? ? nil : @array.push(@array.shift)[index]
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch_after(e)
|
26
|
+
fetch_next(@array.index(e))
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch_before(e)
|
30
|
+
fetch_previous(@array.index(e))
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Docket
|
2
|
+
class RoundRobin
|
3
|
+
|
4
|
+
attr_accessor :storage
|
5
|
+
|
6
|
+
def initialize args={}
|
7
|
+
@storage = args[:storage] || Docket::Storage.new('/tmp/docket.rb')
|
8
|
+
end
|
9
|
+
|
10
|
+
def set identifier, robins, options={}
|
11
|
+
_set identifier, robins, options
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform identifier, action
|
15
|
+
robin = _next_robin identifier
|
16
|
+
action.call(robin)
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def _next_robin identifier
|
22
|
+
list = storage.read(identifier) || []
|
23
|
+
robin_list = RobinList.new(list)
|
24
|
+
|
25
|
+
next_robin = robin_list.fetch_next
|
26
|
+
_set identifier, nil, :list => robin_list.list
|
27
|
+
|
28
|
+
next_robin
|
29
|
+
end
|
30
|
+
|
31
|
+
def _set identifier, robins, options={}
|
32
|
+
list = options[:list] || robins
|
33
|
+
|
34
|
+
storage.save(identifier, list, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'daybreak'
|
2
|
+
|
3
|
+
module Docket
|
4
|
+
class Storage
|
5
|
+
|
6
|
+
attr_accessor :db
|
7
|
+
|
8
|
+
def initialize filename
|
9
|
+
@db = Daybreak::DB.new filename
|
10
|
+
end
|
11
|
+
|
12
|
+
def save key, value, options={}
|
13
|
+
touch do
|
14
|
+
append_to_group(options[:group], key) if options[:group]
|
15
|
+
|
16
|
+
db.set! key, value
|
17
|
+
db.compact
|
18
|
+
db.flush
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def append key, value
|
23
|
+
touch do
|
24
|
+
new_value = Array(read(key)) << value
|
25
|
+
save(key, new_value)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def read key
|
30
|
+
touch { db.get key }
|
31
|
+
end
|
32
|
+
|
33
|
+
def load
|
34
|
+
db.load
|
35
|
+
end
|
36
|
+
|
37
|
+
def close
|
38
|
+
db.close
|
39
|
+
end
|
40
|
+
|
41
|
+
def append_to_group group, value
|
42
|
+
append group, value
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def clear!
|
48
|
+
db.clear
|
49
|
+
end
|
50
|
+
|
51
|
+
def touch &block
|
52
|
+
db.load
|
53
|
+
yield if block_given?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/docket.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docket::Repeater do
|
4
|
+
|
5
|
+
describe '#set' do
|
6
|
+
|
7
|
+
it "sets the schedule" do
|
8
|
+
scheduler_action = lambda { |repeater, frequency|
|
9
|
+
repeater.scheduler.every(frequency, :times => 1) { @thing = "hello" } }
|
10
|
+
|
11
|
+
repeater = Docket::Repeater.new(\
|
12
|
+
:frequencies => ['1s'],
|
13
|
+
:scheduler_action => scheduler_action,
|
14
|
+
:scheduler_set_callback => lambda { |scheduler| },
|
15
|
+
:storage => $storage)
|
16
|
+
|
17
|
+
repeater.set
|
18
|
+
sleep(1.5)
|
19
|
+
repeater.stop
|
20
|
+
|
21
|
+
expect(@thing).to eql('hello')
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with round robin' do
|
25
|
+
|
26
|
+
let(:round_robin) { Docket::RoundRobin.new(:storage => $storage) }
|
27
|
+
|
28
|
+
before :each do
|
29
|
+
$storage.send(:clear!)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "runs a round robin schedule on time" do
|
33
|
+
@trained = Array.new
|
34
|
+
|
35
|
+
round_robin.set("trainer_15", ['dog', 'lion', 'tiger'], :group => '1s')
|
36
|
+
round_robin.set("trainer_16", ['frog', 'lizard', 'snake'], :group => '2s')
|
37
|
+
round_robin.set("trainer_17", ['panda', 'brown', 'black'], :group => '3s')
|
38
|
+
|
39
|
+
scheduler_action = lambda do |repeater, frequency|
|
40
|
+
repeater.scheduler.every(frequency, :times => 1) do
|
41
|
+
repeater.items_for(frequency).each do |key|
|
42
|
+
repeater.perform_on.perform(key, lambda { |robin| @trained << robin })
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
repeater = Docket::Repeater.new(\
|
48
|
+
:frequencies => ['1s', '2s', '3s'],
|
49
|
+
:storage => $storage,
|
50
|
+
:perform_on => round_robin,
|
51
|
+
:scheduler_action => scheduler_action,
|
52
|
+
:repeat => 1
|
53
|
+
)
|
54
|
+
|
55
|
+
repeater.set
|
56
|
+
sleep(3.5)
|
57
|
+
repeater.stop
|
58
|
+
|
59
|
+
expect(@trained.size).to eql(3)
|
60
|
+
expect(@trained).to include('lion', 'lizard', 'brown')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '#repeated_items' do
|
65
|
+
let(:round_robin) { Docket::RoundRobin.new(:storage => $storage) }
|
66
|
+
|
67
|
+
before :each do
|
68
|
+
$storage.send(:clear!)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "lists items that are on repeat" do
|
72
|
+
|
73
|
+
action = lambda { |robin| @animal_to_train = robin }
|
74
|
+
round_robin.set("trainer_15", ['dog', 'lion', 'tiger'], :group => '1w')
|
75
|
+
round_robin.set("trainer_16", ['dog', 'lion', 'tiger'], :group => '5m')
|
76
|
+
round_robin.set("trainer_17", ['dog', 'lion', 'tiger'], :group => '1m')
|
77
|
+
|
78
|
+
scheduler_action = lambda do |scheduler, frequency|
|
79
|
+
scheduler.every(frequency, :times => 1) { }
|
80
|
+
end
|
81
|
+
|
82
|
+
repeater = Docket::Repeater.new(\
|
83
|
+
:frequencies => ['1w', '5m', '1m'],
|
84
|
+
:scheduler_action => scheduler_action,
|
85
|
+
:scheduler_set_callback => lambda { |scheduler| },
|
86
|
+
:storage => $storage,
|
87
|
+
:perform_on => round_robin
|
88
|
+
)
|
89
|
+
|
90
|
+
expect(repeater.repeated_items.size).to eql(3)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docket::RoundRobin do
|
4
|
+
|
5
|
+
let(:round_robin) { Docket::RoundRobin.new(:storage => $storage) }
|
6
|
+
|
7
|
+
describe '#set' do
|
8
|
+
it 'sets a list of robins for some identifier key' do
|
9
|
+
round_robin.set("trainer_15", ['dog', 'lion', 'tiger'])
|
10
|
+
expect($storage.db.get('trainer_15')).to be_kind_of(Array)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#perform' do
|
15
|
+
it "takes the next robin and calls action with it" do
|
16
|
+
action = lambda { |robin| @animal_to_train = robin }
|
17
|
+
round_robin.set("trainer_15", ['dog', 'lion', 'tiger'])
|
18
|
+
|
19
|
+
round_robin.perform("trainer_15", action)
|
20
|
+
expect(@animal_to_train).to eql('lion')
|
21
|
+
|
22
|
+
round_robin.perform("trainer_15", action)
|
23
|
+
expect(@animal_to_train).to eql('tiger')
|
24
|
+
|
25
|
+
round_robin.perform("trainer_15", action)
|
26
|
+
expect(@animal_to_train).to eql('dog')
|
27
|
+
|
28
|
+
round_robin.perform("trainer_15", action)
|
29
|
+
expect(@animal_to_train).to eql('lion')
|
30
|
+
end
|
31
|
+
|
32
|
+
it "persists accross sessions" do
|
33
|
+
action = lambda { |robin| @animal_to_train = robin }
|
34
|
+
|
35
|
+
round_robin.set("trainer_15", ['dog', 'lion', 'tiger'])
|
36
|
+
round_robin.perform("trainer_15", action)
|
37
|
+
|
38
|
+
reload_storage_connection
|
39
|
+
|
40
|
+
round_robin = Docket::RoundRobin.new(:storage => $storage)
|
41
|
+
|
42
|
+
round_robin.perform("trainer_15", action)
|
43
|
+
expect(@animal_to_train).to eql('tiger')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'docket'
|
2
|
+
require 'pry'
|
3
|
+
|
4
|
+
$storage = Docket::Storage.new('/tmp/docket_spec.rb')
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
config.color_enabled = true
|
8
|
+
config.formatter = 'documentation'
|
9
|
+
config.order = 'random'
|
10
|
+
|
11
|
+
config.before(:suite) do
|
12
|
+
$storage.send(:clear!)
|
13
|
+
end
|
14
|
+
|
15
|
+
config.after(:suite) do
|
16
|
+
$storage.close
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def reload_storage_connection
|
22
|
+
if $storage && !$storage.db.closed?
|
23
|
+
$storage.close
|
24
|
+
$storage = Docket::Storage.new('/tmp/docket_spec.rb')
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docket::Storage do
|
4
|
+
|
5
|
+
describe '#new' do
|
6
|
+
it 'creates the storage backend' do
|
7
|
+
expect($storage.db).to_not be_nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#save' do
|
12
|
+
it 'saves the key to the db' do
|
13
|
+
$storage.save 'key1', 'value1'
|
14
|
+
|
15
|
+
expect($storage.db.get('key1')).to eql('value1')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'compacts the db to only have one key' do
|
19
|
+
$storage.send(:clear!)
|
20
|
+
|
21
|
+
$storage.save 'key1', 'value1'
|
22
|
+
reload_storage_connection
|
23
|
+
|
24
|
+
$storage.save 'key1', 'value2'
|
25
|
+
|
26
|
+
expect($storage.db.keys.size).to eql(1)
|
27
|
+
end
|
28
|
+
|
29
|
+
context "using group" do
|
30
|
+
it "writes key to the group list" do
|
31
|
+
$storage.save 'key1_group', 'value1', :group => "test_group1"
|
32
|
+
|
33
|
+
reload_storage_connection
|
34
|
+
|
35
|
+
|
36
|
+
expect($storage.read("test_group1")).to eql(['key1_group'])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#read' do
|
42
|
+
it 'returns value set for key in db' do
|
43
|
+
$storage.save 'key1', 'value1'
|
44
|
+
expect($storage.read('key1')).to eql('value1')
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#append' do
|
49
|
+
context 'key does not exist' do
|
50
|
+
it 'creates key and appends' do
|
51
|
+
$storage.append 'append_key', 2
|
52
|
+
|
53
|
+
reload_storage_connection
|
54
|
+
|
55
|
+
|
56
|
+
expect($storage.read('append_key')).to eql([2])
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'key exists' do
|
61
|
+
|
62
|
+
it "appends value to the end of a list value for key" do
|
63
|
+
$storage.save 'key1', [1]
|
64
|
+
$storage.append 'key1', 2
|
65
|
+
|
66
|
+
reload_storage_connection
|
67
|
+
|
68
|
+
|
69
|
+
expect($storage.read('key1')).to eql([1,2])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
metadata
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: docket
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Hubert Liu
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2014-03-05 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 5
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 5
|
32
|
+
version: "1.5"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rake
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: rspec
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
type: :development
|
62
|
+
version_requirements: *id003
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: pry
|
65
|
+
prerelease: false
|
66
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
72
|
+
segments:
|
73
|
+
- 0
|
74
|
+
version: "0"
|
75
|
+
type: :development
|
76
|
+
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: daybreak
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :runtime
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: rufus-scheduler
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :runtime
|
104
|
+
version_requirements: *id006
|
105
|
+
description: Helps schedule jobs
|
106
|
+
email:
|
107
|
+
- hubert.liu@rigor.com
|
108
|
+
executables: []
|
109
|
+
|
110
|
+
extensions: []
|
111
|
+
|
112
|
+
extra_rdoc_files: []
|
113
|
+
|
114
|
+
files:
|
115
|
+
- .gitignore
|
116
|
+
- .travis.yml
|
117
|
+
- Gemfile
|
118
|
+
- LICENSE.txt
|
119
|
+
- README.md
|
120
|
+
- Rakefile
|
121
|
+
- docket.gemspec
|
122
|
+
- example.db
|
123
|
+
- lib/docket.rb
|
124
|
+
- lib/docket/repeater.rb
|
125
|
+
- lib/docket/robin_list.rb
|
126
|
+
- lib/docket/round_robin.rb
|
127
|
+
- lib/docket/storage.rb
|
128
|
+
- lib/docket/version.rb
|
129
|
+
- spec/repeater_spec.rb
|
130
|
+
- spec/round_robin_spec.rb
|
131
|
+
- spec/spec_helper.rb
|
132
|
+
- spec/storage_spec.rb
|
133
|
+
homepage: ""
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
|
139
|
+
require_paths:
|
140
|
+
- lib
|
141
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
142
|
+
none: false
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
hash: 3
|
147
|
+
segments:
|
148
|
+
- 0
|
149
|
+
version: "0"
|
150
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
none: false
|
152
|
+
requirements:
|
153
|
+
- - ">="
|
154
|
+
- !ruby/object:Gem::Version
|
155
|
+
hash: 3
|
156
|
+
segments:
|
157
|
+
- 0
|
158
|
+
version: "0"
|
159
|
+
requirements: []
|
160
|
+
|
161
|
+
rubyforge_project:
|
162
|
+
rubygems_version: 1.8.15
|
163
|
+
signing_key:
|
164
|
+
specification_version: 3
|
165
|
+
summary: Helps schedule jobs
|
166
|
+
test_files:
|
167
|
+
- spec/repeater_spec.rb
|
168
|
+
- spec/round_robin_spec.rb
|
169
|
+
- spec/spec_helper.rb
|
170
|
+
- spec/storage_spec.rb
|