scheduled_job 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4e5e1e7a35d0f3d68c2428b653941ccef7161544
4
+ data.tar.gz: cc91a8c1b338f203665d2c9e4022fcdf421bb761
5
+ SHA512:
6
+ metadata.gz: bc188dc562bc3871f5bb1da987c834c7e040ef57a57532b1e129f442a1d65b6a46ffe54f0abe4897e92a3d4b1d2ea3299a752a7e1e77ed8406ee8b4dc00aeb2e
7
+ data.tar.gz: 613e68e70fd21d1d05b27ef8154deea6322bc4d7c60da50452bb793a1dbaada71305b5f35223840de2abf2271ef4f168834c2eb9d41e212721c116d177baa296
data/.gitignore ADDED
@@ -0,0 +1,17 @@
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
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1.1
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.1.1
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ # 0.0.2
2
+ Initial public release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in scheduled_job.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 RightScale
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,149 @@
1
+ # ScheduledJob
2
+
3
+ Scheduled job looks to build on top of the [delayed_job](https://github.com/collectiveidea/delayed_job) project by adding support for jobs that need to recur. Whilst investigating other options we decided that we wanted a very light weight framework that would simply allow us to define worker tasks that need to happen on a regular basis.
4
+
5
+ In order to achieve this we created the following interface which allows the developer to consisly define what the job is to do as well as when it is to run. This helps keep all the logic in one place which is a huge plus.
6
+
7
+ In terms of implementation there are only a couple of things we need to do.
8
+
9
+ Firstly if there are any before or success callbacks you need to define you can do this via the configure block. This passes the instance of DelayedJob that run your job as well as the job itself.
10
+
11
+ We can also take this opportunity to set up any logging. By default we use the ruby logger but if you are using rails for example you can do something like the following:
12
+
13
+ ```ruby
14
+ ScheduledJob.configure do |config|
15
+ config.before_callback = -> (job, scheduled_job) do
16
+ JobRunLogger.update_attributes!(job_name: scheduled_job.class.name, started_at: Time.now.utc)
17
+ end
18
+
19
+ config.success_callback = -> (job, _) do
20
+ ScheduledJob.logger.info("Hurrah my job #{job.id} has completed")
21
+ end
22
+
23
+ config.logger = Rails.logger
24
+ end
25
+ ```
26
+
27
+ With this in place we can go on to define a job that we want to run regularly. To do this just mix in the scheduled job module in your class, define a perform method and define a time to recur.
28
+
29
+ ```ruby
30
+ class WeeklyMetricJob
31
+ include ::ScheduledJob
32
+
33
+ def perform
34
+ ScheduledJob.logger.info('I need to do something over and over')
35
+ end
36
+
37
+ def self.time_to_recur(last_run_at)
38
+ last_run_at.end_of_week + 3.hours
39
+ end
40
+ end
41
+ ```
42
+
43
+ This allows you so specify what logic you need to run along side how often it needs to run. The time to recur is passed the completion time of the last successful run so you can use whatever logic you like in here to define when the job needs to run again.
44
+
45
+ Finally you need to kick off the job the first time. Once it has run successfully it will look after itself but to start the cycle you need to run schedule_job on your job. Continuing on the example above:
46
+
47
+ ```ruby
48
+ WeeklyMetricJob.schedule_job
49
+ ```
50
+
51
+ Note currently this implementation is dependant upon using the [delayed_job_active_record](https://github.com/collectiveidea/delayed_job_active_record) backend. This is something that we may be looking to remove in future.
52
+
53
+ ## Running the specs
54
+
55
+ This is the default rake task so you can run the specs in any of the following ways:
56
+
57
+ ```bash
58
+ bundle exec rake
59
+ bundle exec rake spec
60
+ bundle exec rspec
61
+ ```
62
+
63
+ ## Getting a console
64
+
65
+ The project is currently using pry. In order to get a console in the context of the project just run the pry.rb file in ruby.
66
+
67
+ ```bash
68
+ bundle exec ruby pry.rb
69
+ ```
70
+
71
+ ## Installation
72
+
73
+ Add this line to your application's Gemfile:
74
+
75
+ gem 'scheduled_job'
76
+
77
+ And then execute:
78
+
79
+ $ bundle
80
+
81
+ Or install it yourself as:
82
+
83
+ $ gem install scheduled_job
84
+
85
+ ## Usage
86
+
87
+ First you must include the scheduled job module in any DelayedJob that needs to run on a regular basis.
88
+
89
+ ```ruby
90
+ include ::ScheduledJob
91
+ ```
92
+
93
+ Then you need to say what the job is acutally to do. This is done by implementing the permform method.
94
+
95
+ ```ruby
96
+ def perform
97
+ puts 'I do work!'
98
+ end
99
+ ```
100
+
101
+ Finaly we need to write the logic for when we want the job to run. This is done by implementing the time_to_recur method which is passed the time the job last completed as its parameter.
102
+
103
+ ```ruby
104
+ def self.time_to_recur(last_run_at)
105
+ last_run_at + 3.hours
106
+ end
107
+ ```
108
+
109
+ There are also callbacks that are available using ScheduledJob. These allow you to hook into the scheduling life cycle. Also note that as this uses DelayedJob under the hood all of the delayed job callbacks are still available for use.
110
+
111
+ These can be defined when configuring the gem for you application on the configure block:
112
+
113
+ ```ruby
114
+ ScheduledJob.configure do |config|
115
+ # configuration code in here
116
+ end
117
+ ```
118
+
119
+ The before_callback is executed before the perform method is called on the scheduled job. This is passed the delayed job object and the scheduled job instance.
120
+
121
+ ```ruby
122
+ config.before_callback = -> (job, scheduled_job) do
123
+ JobRunLogger.update_attributes!(job_name: scheduled_job.class.name, started_at: Time.now.utc)
124
+ end
125
+ ```
126
+
127
+ The success_callback is called on sucessful completion of the job and is also passed the delayed job object and the scheduled job instance.
128
+
129
+ ```ruby
130
+ config.success_callback = -> (job, _) do
131
+ ScheduledJob.logger.info("Hurrah my job #{job.id} has completed")
132
+ end
133
+ ```
134
+
135
+ Then there is the fast mode. This is checked prior to scheduling another run of your job e.g. after a job has completed. This allows you to override the scheduling logic and ask the job to run immediatly. This is passed the scheduled job class. This means you can have state stored elsewhere to change the scheduling without having to modify the code. This could be getting an array from a database for example:
136
+
137
+ ```ruby
138
+ config.fast_mode = -> (job) do
139
+ Database.get_value('fast_mode_jobs').include?(job.name)
140
+ end
141
+ ```
142
+
143
+ ## Contributing
144
+
145
+ 1. Fork it ( http://github.com/rightscale/scheduled_job/fork )
146
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
147
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
148
+ 4. Push to the branch (`git push origin my-new-feature`)
149
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -0,0 +1,91 @@
1
+ require "scheduled_job/version"
2
+ require 'logger'
3
+ require 'delayed_job'
4
+ require 'delayed_job_active_record'
5
+
6
+ module ScheduledJob
7
+ class << self
8
+ attr_accessor :config
9
+ end
10
+
11
+ def self.logger
12
+ self.config.logger
13
+ end
14
+
15
+ def self.configure
16
+ self.config ||= Config.new
17
+ yield(config)
18
+ end
19
+
20
+ class Config
21
+ attr_accessor :logger, :before_callback, :success_callback, :fast_mode
22
+
23
+ def initialize
24
+ @logger = Logger.new(STDOUT)
25
+ end
26
+ end
27
+
28
+ def self.included(base)
29
+ base.extend ScheduledJobClassMethods
30
+ end
31
+
32
+ def before(job)
33
+ callback = ScheduledJob.config.before_callback
34
+ callback.call(job, self) if callback
35
+ end
36
+
37
+ def success(job)
38
+ callback = ScheduledJob.config.success_callback
39
+ callback.call(job, self) if callback
40
+ GC.start
41
+ self.class.schedule_job(job)
42
+ end
43
+
44
+ def failure(job)
45
+ ScheduledJob.logger.error("DelayedJob failed: processing job in queue #{self.class.queue_name} failed")
46
+ job.update_attributes!(:failed_at => Time.now)
47
+ self.class.schedule_job
48
+ end
49
+
50
+ def error(job, exception)
51
+ ScheduledJob.logger.warn("DelayedJob error: Job: #{job.id}, in queue #{self.class.queue_name}, exception: #{exception}")
52
+ self.class.schedule_job
53
+ end
54
+
55
+ module ScheduledJobClassMethods
56
+ # This method should be called when scheduling a recurring job as it checks to ensure no
57
+ # other instances of the job are already running.
58
+ def schedule_job(job = nil)
59
+ unless job_exists?(job)
60
+ callback = ScheduledJob.config.fast_mode
61
+ in_fast_mode = callback ? callback.call(self) : false
62
+
63
+ run_at = in_fast_mode ? Time.now.utc : time_to_recur(Time.now.utc)
64
+
65
+ Delayed::Job.enqueue(new, :run_at => run_at, :queue => queue_name)
66
+ end
67
+ end
68
+
69
+ def queue_name
70
+ "Default"
71
+ end
72
+
73
+ def random_minutes(base, random_delta)
74
+ random_delta *= -1 if random_delta < 0
75
+ (base + Random.new.rand((-1 * random_delta)..random_delta)).minutes
76
+ end
77
+
78
+ def job_exists?(job = nil)
79
+ conditions = ['handler like ? AND failed_at IS NULL', "%#{self.name}%"]
80
+ unless job.blank?
81
+ conditions[0] << " AND id != ?"
82
+ conditions << job.id
83
+ end
84
+ Delayed::Job.exists?(conditions)
85
+ end
86
+
87
+ def run_duration_threshold
88
+ self.const_defined?(:RUN_DURATION_THRESHOLD) ? self::RUN_DURATION_THRESHOLD : nil
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,3 @@
1
+ module ScheduledJob
2
+ VERSION = "0.0.2"
3
+ end
data/pry.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'scheduled_job'
2
+ require 'pry'
3
+
4
+ ScheduledJob.configure {}
5
+
6
+ binding.pry
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'scheduled_job/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "scheduled_job"
8
+ spec.version = ScheduledJob::VERSION
9
+ spec.authors = ["CallumD", "aliscott", "smcgivern", "alikhajeh1"]
10
+ spec.email = ["callum.dryden@rightscale.com", "alistair@rightscale.com", "sean.mcgivern@rightscale.com", "ali@rightscale.com"]
11
+ spec.summary = %q{Adding support for jobs that need to reccur}
12
+ spec.description = %q{By including the scheduled job module in a delayed job you can specify when you would like the job to run again. Currently this is intented to be used with the active record back end this may change in future.}
13
+ spec.homepage = "https://github.com/rightscale/scheduled_job"
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_runtime_dependency "delayed_job", "3.0.5"
22
+ spec.add_runtime_dependency "delayed_job_active_record", "0.4.4"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.5"
25
+ spec.add_development_dependency "rake", "~> 0.9"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "pry"
28
+ spec.add_development_dependency "simplecov"
29
+ end
@@ -0,0 +1,9 @@
1
+ ruby do
2
+ version '2.1.1'
3
+ gemset 'scheduled_job'
4
+ end
5
+ bundler do
6
+ version '1.5.3'
7
+ exclusions 'deployment'
8
+ bundle_path File.join(ENV["HOME"], '.rightscale', 'scheduled_job')
9
+ end
@@ -0,0 +1,137 @@
1
+ require 'spec_helper'
2
+ require 'pry'
3
+
4
+ class UnderTest
5
+ include ScheduledJob
6
+
7
+ def self.queue_name
8
+ "TESTING"
9
+ end
10
+
11
+ def self.time_to_recur(last_run_time)
12
+ "time to recur"
13
+ end
14
+
15
+ def perform
16
+ end
17
+ end
18
+
19
+ describe ScheduledJob do
20
+
21
+ let(:under_test) { UnderTest.new }
22
+
23
+ describe 'fast mode' do
24
+ before { expect(Delayed::Job).to receive(:exists?).and_return(false) }
25
+
26
+ context 'when the job is not in run fast mode' do
27
+ it 'uses the value from time to recur' do
28
+ Delayed::Job.should_receive(:enqueue).with(anything, {
29
+ :run_at => UnderTest.time_to_recur(nil),
30
+ :queue => UnderTest.queue_name
31
+ })
32
+ UnderTest.schedule_job
33
+ end
34
+ end
35
+
36
+ context 'when the job is in run fast mode' do
37
+ before do
38
+ ScheduledJob.configure do |config|
39
+ config.fast_mode = -> (_) do
40
+ true
41
+ end
42
+ end
43
+ end
44
+ it 'uses the current time' do
45
+ time = Time.now.utc
46
+ Time.stub_chain(:now, :utc) { time }
47
+
48
+ Delayed::Job.should_receive(:enqueue).with(anything, {
49
+ :run_at => time,
50
+ :queue => UnderTest.queue_name
51
+ })
52
+ UnderTest.schedule_job
53
+ end
54
+ end
55
+ end
56
+
57
+ it "implements the required interface" do
58
+ expect(UnderTest).to respond_to :queue_name
59
+ expect(under_test).to respond_to :perform
60
+ expect(UnderTest).to respond_to :time_to_recur
61
+ expect(UnderTest).to respond_to :random_minutes
62
+ end
63
+
64
+ it "adds success to the class" do
65
+ expect(under_test).to respond_to :success
66
+ end
67
+
68
+ it "schedules a new job on success" do
69
+ expect(UnderTest).to receive(:schedule_job)
70
+ Delayed::Job.stub(:enqueue)
71
+ underTestJob = double("UnderTestJob");
72
+ underTestJob.stub(:run_at) { DateTime.now.utc }
73
+ underTestJob.stub(:id) { 1 }
74
+ under_test.before underTestJob
75
+ under_test.success underTestJob
76
+ end
77
+
78
+ it "adds failure to the class" do
79
+ expect(under_test).to respond_to :failure
80
+ end
81
+
82
+ it "logs the error and schedules a job on failure" do
83
+ dummy_job = double("job")
84
+ dummy_job.stub(:id)
85
+ expect(dummy_job).to receive(:update_attributes!)
86
+ expect(ScheduledJob.logger).to receive(:error)
87
+ expect(UnderTest).to receive(:schedule_job)
88
+ Delayed::Job.stub(:enqueue)
89
+ under_test.failure(dummy_job)
90
+ end
91
+
92
+ it "adds error to the class" do
93
+ expect(under_test).to respond_to :error
94
+ end
95
+
96
+ it "logs on error" do
97
+ job = double("job")
98
+ job.stub(:id) { 4 }
99
+ expect(ScheduledJob.logger).to receive(:warn)
100
+ UnderTest.stub(:schedule_job)
101
+ under_test.error job, nil
102
+ end
103
+
104
+ it "wraps delayed job with scheduled_job" do
105
+ job = double("job")
106
+ job.stub(:id) { 4 }
107
+ instance = double("instance")
108
+ UnderTest.stub(:new) { instance }
109
+ expect(Delayed::Job).to receive(:exists?).and_return(false)
110
+ expect(Delayed::Job).to receive(:enqueue).with(instance, run_at: "time to recur", queue: "TESTING")
111
+ UnderTest.schedule_job job
112
+ end
113
+
114
+ it "scheduled a job even if there is total failure and an existing job" do
115
+ dummy_job = double("job")
116
+ dummy_job.stub(:id)
117
+ expect(dummy_job).to receive(:update_attributes!)
118
+ expect(Delayed::Job).to receive(:exists?).twice.and_return(false)
119
+ expect(Delayed::Job).to receive(:enqueue).exactly(2).times
120
+ UnderTest.schedule_job
121
+ under_test.failure(dummy_job)
122
+ end
123
+
124
+ describe '#random_minutes' do
125
+ it 'returns a random number with a base and delta' do
126
+ expect(UnderTest.random_minutes(60, 10)).to be_within(10 * 60).of(60 * 60)
127
+ end
128
+
129
+ it 'returns a random number when called with a negative delta' do
130
+ expect(UnderTest.random_minutes(10, -2)).to be_within(2 * 60).of(10 * 60)
131
+ end
132
+
133
+ it 'returns base when called with delta of 0' do
134
+ expect(UnderTest.random_minutes(5, 0)).to be_within(0).of(5 * 60)
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,16 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'bundler/setup'
5
+ Bundler.setup
6
+
7
+ require 'scheduled_job' # and any other gems you need
8
+ require 'logger'
9
+
10
+ ScheduledJob.configure do |config|
11
+ config.logger = Logger.new(nil)
12
+ end
13
+
14
+ RSpec.configure do |config|
15
+ # some (optional) config here
16
+ end
metadata ADDED
@@ -0,0 +1,168 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scheduled_job
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - CallumD
8
+ - aliscott
9
+ - smcgivern
10
+ - alikhajeh1
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2014-07-18 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: delayed_job
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - '='
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.5
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 3.0.5
30
+ - !ruby/object:Gem::Dependency
31
+ name: delayed_job_active_record
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '='
35
+ - !ruby/object:Gem::Version
36
+ version: 0.4.4
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - '='
42
+ - !ruby/object:Gem::Version
43
+ version: 0.4.4
44
+ - !ruby/object:Gem::Dependency
45
+ name: bundler
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '1.5'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '1.5'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '0.9'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '0.9'
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ - !ruby/object:Gem::Dependency
87
+ name: pry
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ - !ruby/object:Gem::Dependency
101
+ name: simplecov
102
+ requirement: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ description: By including the scheduled job module in a delayed job you can specify
115
+ when you would like the job to run again. Currently this is intented to be used
116
+ with the active record back end this may change in future.
117
+ email:
118
+ - callum.dryden@rightscale.com
119
+ - alistair@rightscale.com
120
+ - sean.mcgivern@rightscale.com
121
+ - ali@rightscale.com
122
+ executables: []
123
+ extensions: []
124
+ extra_rdoc_files: []
125
+ files:
126
+ - ".gitignore"
127
+ - ".ruby-version"
128
+ - ".travis.yml"
129
+ - CHANGELOG.md
130
+ - Gemfile
131
+ - LICENSE.txt
132
+ - README.md
133
+ - Rakefile
134
+ - lib/scheduled_job.rb
135
+ - lib/scheduled_job/version.rb
136
+ - pry.rb
137
+ - scheduled_job.gemspec
138
+ - scheduled_job.rconf
139
+ - spec/lib/scheduled_job_spec.rb
140
+ - spec/spec_helper.rb
141
+ homepage: https://github.com/rightscale/scheduled_job
142
+ licenses:
143
+ - MIT
144
+ metadata: {}
145
+ post_install_message:
146
+ rdoc_options: []
147
+ require_paths:
148
+ - lib
149
+ required_ruby_version: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ requirements: []
160
+ rubyforge_project:
161
+ rubygems_version: 2.2.2
162
+ signing_key:
163
+ specification_version: 4
164
+ summary: Adding support for jobs that need to reccur
165
+ test_files:
166
+ - spec/lib/scheduled_job_spec.rb
167
+ - spec/spec_helper.rb
168
+ has_rdoc: