rufus-runner 0.0.3
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/LICENSE.txt +22 -0
- data/README.md +67 -0
- data/bin/rufus-runner +18 -0
- data/lib/rufus-runner/tracking_scheduler/forking_job_runner.rb +37 -0
- data/lib/rufus-runner/tracking_scheduler/job_runner.rb +56 -0
- data/lib/rufus-runner/tracking_scheduler/threading_job_runner.rb +16 -0
- data/lib/rufus-runner/tracking_scheduler.rb +159 -0
- data/lib/rufus-runner/version.rb +5 -0
- data/lib/rufus-runner.rb +2 -0
- data/rufus-runner.gemspec +45 -0
- metadata +211 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 026ca77e2c60d3b31c2930dd9c8bf03e5fb08478
|
4
|
+
data.tar.gz: f20bf4a2f524d4700765805266a6592436655c59
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c3ad75069a777e751f8d57b6b440061b69cc3bccf85d31580d1e85cfd4b44258ee6a3d864ed974c437d521e979d0a00f7e59d7be30f6d1f35f6b6eee1bef7811
|
7
|
+
data.tar.gz: 5cbd8a66992378eea954e891845c585368b401f641d9b0e8384158f7e8d50b40200e6821821ba815205445641aa0694711f9e60bea8bc875406b83af5e1bbbf5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 HouseTrip
|
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,67 @@
|
|
1
|
+
# rufus-runner
|
2
|
+
|
3
|
+
[](https://travis-ci.org/HouseTrip/rufus-runner)
|
4
|
+
|
5
|
+
Wraps [rufus-scheduler](http://github.com/jmettraux/rufus-scheduler) in a
|
6
|
+
standalone process, with job timing, logging, and safe defaults.
|
7
|
+
|
8
|
+
**Note: I did not write this gem, only deployed it to RubyGems. The project appears to be dead and I'll provide
|
9
|
+
support the best I can. If the original authors decide they want to take it back over, just let me know.**
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Add this line to your application's Gemfile:
|
14
|
+
|
15
|
+
gem 'rufus-runner'
|
16
|
+
$ bundle
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
|
20
|
+
$ gem install rufus-runner
|
21
|
+
|
22
|
+
Create a configuration file:
|
23
|
+
|
24
|
+
# config/schedule.rb
|
25
|
+
Rufus::TrackingScheduler.start do |scheduler|
|
26
|
+
# sentinel job that keeps running to prove Rufus is still alive
|
27
|
+
scheduler.run :name => 'no-op', :every => '60s' do
|
28
|
+
Kernel.sleep(1e-3)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
The `#run` method simply takes the same options as Rufus's `#every` method,
|
33
|
+
with these safe defaults:
|
34
|
+
|
35
|
+
:mutex => <m> # because Rails is not thread-safe
|
36
|
+
:timeout => 60 # we don't want no long-running jobs, they should be DJ'd (seconds)
|
37
|
+
:discard_past => true # don't catch up with past jobs
|
38
|
+
:allow_overlapping => false # don't try to run the same job twice simultaneously
|
39
|
+
|
40
|
+
Where `<m>` is a shared, global instance of `Mutex`.
|
41
|
+
|
42
|
+
Finally, run it:
|
43
|
+
|
44
|
+
$ rufus-runner config/schedule.rb
|
45
|
+
|
46
|
+
|
47
|
+
### Rails
|
48
|
+
|
49
|
+
If you're running Rails, you might want to have an environment loaded in the
|
50
|
+
scheduler. Simply add on top of your schedule:
|
51
|
+
|
52
|
+
# Rails 2
|
53
|
+
require 'config/boot'
|
54
|
+
require 'config/environment'
|
55
|
+
|
56
|
+
# Rails 3
|
57
|
+
require 'config/application'
|
58
|
+
|
59
|
+
When Rails is present, `rufus-runner` will call `ActiveRecord::Base.clear_active_connections!` after each job for you.
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
1. Fork it
|
64
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
65
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
66
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
67
|
+
5. Create new Pull Request
|
data/bin/rufus-runner
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Driver for Rufus-scheduler.
|
4
|
+
# Pass it a schedule file as a command-line argument
|
5
|
+
#
|
6
|
+
$PROGRAM_NAME = 'rufus'
|
7
|
+
|
8
|
+
require 'rubygems'
|
9
|
+
require 'pathname'
|
10
|
+
require 'bundler/setup'
|
11
|
+
require 'rufus-runner'
|
12
|
+
|
13
|
+
if ARGV.empty?
|
14
|
+
puts 'Sorry, but I need a schedule. Pass it to me as the first command-line argument.'
|
15
|
+
Process.exit! 1
|
16
|
+
end
|
17
|
+
|
18
|
+
load File.expand_path(ARGV[0])
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rufus-runner/tracking_scheduler/job_runner'
|
2
|
+
|
3
|
+
class Rufus::TrackingScheduler::ForkingJobRunner < Rufus::TrackingScheduler::JobRunner
|
4
|
+
|
5
|
+
class UnexpectedExitStatus < StandardError; end
|
6
|
+
|
7
|
+
def run_block
|
8
|
+
@pid = fork do
|
9
|
+
$PROGRAM_NAME = "rufus: #{@name}"
|
10
|
+
@block.call
|
11
|
+
exit 0
|
12
|
+
end
|
13
|
+
status = Process.wait2(@pid)[1]
|
14
|
+
unless status.success?
|
15
|
+
raise UnexpectedExitStatus.new(status.exitstatus)
|
16
|
+
end
|
17
|
+
rescue Rufus::Scheduler::TimeOutError
|
18
|
+
log("timed out, killing")
|
19
|
+
kill
|
20
|
+
raise
|
21
|
+
end
|
22
|
+
|
23
|
+
def shutdown
|
24
|
+
kill
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def kill
|
31
|
+
Process.kill("KILL", @pid)
|
32
|
+
Process.wait(@pid)
|
33
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
34
|
+
# process already dead, which is fine
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
class Rufus::Scheduler::Job
|
2
|
+
attr_accessor :job_runner
|
3
|
+
end
|
4
|
+
|
5
|
+
class Rufus::TrackingScheduler::JobRunner
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@name = options.fetch(:name)
|
9
|
+
@job = options.fetch(:job)
|
10
|
+
@block = options.fetch(:block)
|
11
|
+
@scheduler = options.fetch(:scheduler)
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
return if @scheduler.shutting_down?
|
16
|
+
@job.job_runner = self
|
17
|
+
start_time = Time.now
|
18
|
+
log("starting")
|
19
|
+
|
20
|
+
begin
|
21
|
+
run_block
|
22
|
+
rescue Exception => exception
|
23
|
+
log("failed with #{exception.class.name} (#{exception.message})")
|
24
|
+
if defined?(ActiveRecord::ConnectionTimeoutError) && exception.kind_of?(ActiveRecord::ConnectionTimeoutError)
|
25
|
+
log("connection broken, exiting scheduler")
|
26
|
+
exit 0
|
27
|
+
end
|
28
|
+
else
|
29
|
+
total_time = Time.now - start_time
|
30
|
+
log("completed in %.3f s" % total_time)
|
31
|
+
end
|
32
|
+
|
33
|
+
if defined?(ActiveRecord::Base)
|
34
|
+
ActiveRecord::Base.clear_active_connections!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def shutdown
|
39
|
+
raise NotImplementedError.new
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def run_block
|
45
|
+
raise NotImplementedError.new
|
46
|
+
end
|
47
|
+
|
48
|
+
def job_id
|
49
|
+
@job_id ||= '%08x' % @job.job_id.gsub(/\D/,'')
|
50
|
+
end
|
51
|
+
|
52
|
+
def log(message)
|
53
|
+
@scheduler.log("#{@name}(#{job_id}): #{message}")
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rufus-runner/tracking_scheduler/job_runner'
|
2
|
+
|
3
|
+
class Rufus::TrackingScheduler::ThreadingJobRunner < Rufus::TrackingScheduler::JobRunner
|
4
|
+
|
5
|
+
def shutdown
|
6
|
+
# nothing to do, threads will die automatically
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def run_block
|
13
|
+
@block.call
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
class Rufus::TrackingScheduler
|
2
|
+
end
|
3
|
+
|
4
|
+
require 'rufus/scheduler'
|
5
|
+
require 'eventmachine'
|
6
|
+
require 'rufus-runner/tracking_scheduler/threading_job_runner'
|
7
|
+
require 'rufus-runner/tracking_scheduler/forking_job_runner'
|
8
|
+
|
9
|
+
#
|
10
|
+
# Wraps Rufus's scheduler class with signal handling,
|
11
|
+
# cancellation of jobs, and logging.
|
12
|
+
#
|
13
|
+
class Rufus::TrackingScheduler
|
14
|
+
# wait that long for jobs to complete before quitting (seconds)
|
15
|
+
GRACE_DELAY = 10
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
@options = DefaultOptions.merge(options)
|
19
|
+
@scheduler = Rufus::Scheduler::EmScheduler.start_new
|
20
|
+
log('scheduler started')
|
21
|
+
end
|
22
|
+
|
23
|
+
def run(options={}, &block)
|
24
|
+
return unless rails_environment_matches?(options.delete(:environments))
|
25
|
+
options = @options.merge(options)
|
26
|
+
|
27
|
+
name = options.delete(:name) || 'noname'
|
28
|
+
case options.delete(:fork) || :thread
|
29
|
+
when :thread
|
30
|
+
job_runner_class = ThreadingJobRunner
|
31
|
+
when :process
|
32
|
+
job_runner_class = ForkingJobRunner
|
33
|
+
else
|
34
|
+
fail ArgumentError.new("option :fork needs to be either :thread or :process")
|
35
|
+
end
|
36
|
+
|
37
|
+
schedule(options) do |job|
|
38
|
+
job_runner = job_runner_class.new(
|
39
|
+
:name => name,
|
40
|
+
:job => job,
|
41
|
+
:block => block,
|
42
|
+
:scheduler => self
|
43
|
+
)
|
44
|
+
job_runner.run
|
45
|
+
end
|
46
|
+
|
47
|
+
log("scheduled '#{name}'")
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.start(options = {})
|
52
|
+
EM.run do
|
53
|
+
scheduler = new(options)
|
54
|
+
scheduler.send :setup_traps
|
55
|
+
yield scheduler
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def shutting_down!
|
60
|
+
@shutting_down = true
|
61
|
+
end
|
62
|
+
|
63
|
+
def shutting_down?
|
64
|
+
!!@shutting_down
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def log(string)
|
69
|
+
$stdout.write "[#{$PROGRAM_NAME} #{format_time Time.now}] #{string}\n"
|
70
|
+
$stdout.flush
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def schedule(options, &block)
|
76
|
+
if frequency = options.delete(:every)
|
77
|
+
scheduling_method = :every
|
78
|
+
elsif frequency = options.delete(:cron)
|
79
|
+
scheduling_method = :cron
|
80
|
+
else
|
81
|
+
raise ArgumentError.new('You need to specify either :every or :cron')
|
82
|
+
end
|
83
|
+
|
84
|
+
@scheduler.send(scheduling_method, frequency, options, &block)
|
85
|
+
end
|
86
|
+
|
87
|
+
def setup_traps
|
88
|
+
%w(INT TERM).each do |signal|
|
89
|
+
Signal.trap(signal) do
|
90
|
+
log "SIG#{signal} received"
|
91
|
+
# EM uses mutexes, which cannot be used in the context of a trap.
|
92
|
+
# Just do the cleanup in a thread
|
93
|
+
Thread.new {
|
94
|
+
stop_all_jobs
|
95
|
+
EM.stop_event_loop
|
96
|
+
}.join
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def stop_all_jobs
|
102
|
+
shutting_down!
|
103
|
+
@scheduler.jobs.each_pair do |job_id, job|
|
104
|
+
job.unschedule
|
105
|
+
end
|
106
|
+
log "all jobs unscheduled"
|
107
|
+
if running_jobs_count == 0
|
108
|
+
log "no more jobs running"
|
109
|
+
return
|
110
|
+
end
|
111
|
+
|
112
|
+
log "waiting for #{running_jobs_count} still running jobs"
|
113
|
+
start_time = Time.now
|
114
|
+
while (Time.now <= start_time + GRACE_DELAY) && (running_jobs_count > 0)
|
115
|
+
Kernel.sleep(100e-3)
|
116
|
+
end
|
117
|
+
|
118
|
+
if running_jobs_count > 0
|
119
|
+
log "#{running_jobs_count} jobs did not complete"
|
120
|
+
@scheduler.running_jobs.collect(&:job_runner).each(&:shutdown)
|
121
|
+
else
|
122
|
+
log "all jobs completed"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def running_jobs_count
|
127
|
+
@scheduler.running_jobs.length
|
128
|
+
end
|
129
|
+
|
130
|
+
def format_time(time)
|
131
|
+
"%s.%03d" % [time.strftime('%F %T'), ((time.to_f - time.to_i) * 1e3).to_i]
|
132
|
+
end
|
133
|
+
|
134
|
+
def rails_environment_matches?(environments)
|
135
|
+
return true unless rails_environment
|
136
|
+
return true if environments.nil?
|
137
|
+
|
138
|
+
Array(environments).any? do |environment|
|
139
|
+
# environment can be a string or a regexp
|
140
|
+
environment === rails_environment
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def rails_environment
|
145
|
+
if defined?(Rails)
|
146
|
+
Rails.env
|
147
|
+
else
|
148
|
+
ENV['RAILS_ENV'] || ENV['RACK_ENV']
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
DefaultOptions = {
|
153
|
+
:fork => :process, # safety first
|
154
|
+
:mutex => Mutex.new, # because Rails is not thread-safe
|
155
|
+
:timeout => 60, # we don't want no long-running jobs, they should be DJ'd (seconds)
|
156
|
+
:discard_past => true, # don't catch up with past jobs
|
157
|
+
:allow_overlapping => false, # don't try to run the same job twice simultaneously
|
158
|
+
}
|
159
|
+
end
|
data/lib/rufus-runner.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$:.unshift(lib) unless $:.include?(lib)
|
5
|
+
require 'rufus-runner/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = "rufus-runner"
|
9
|
+
gem.version = Rufus::Runner::VERSION
|
10
|
+
gem.license = 'MIT'
|
11
|
+
gem.authors = ["Julien Letessier", "Chuck Callebs"]
|
12
|
+
gem.email = ["julien.letessier@gmail.com", "chuck@callebs.io"]
|
13
|
+
gem.description = %q{Wrapper process around rufus-scheduler}
|
14
|
+
gem.summary = %q{Wrapper process around rufus-scheduler}
|
15
|
+
gem.homepage = "http://github.com/ccallebs/rufus-runner"
|
16
|
+
|
17
|
+
gem.add_runtime_dependency 'eventmachine'
|
18
|
+
gem.add_runtime_dependency 'rufus-scheduler', '~> 2.0.23'
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake'
|
21
|
+
gem.add_development_dependency 'rspec', '~> 2'
|
22
|
+
gem.add_development_dependency 'rb-inotify'
|
23
|
+
gem.add_development_dependency 'rb-fsevent'
|
24
|
+
gem.add_development_dependency 'rb-fchange'
|
25
|
+
gem.add_development_dependency 'terminal-notifier-guard'
|
26
|
+
gem.add_development_dependency 'pry'
|
27
|
+
gem.add_development_dependency 'pry-nav'
|
28
|
+
gem.add_development_dependency 'rspec-instafail'
|
29
|
+
|
30
|
+
gem.files = %w(
|
31
|
+
LICENSE.txt
|
32
|
+
README.md
|
33
|
+
bin/rufus-runner
|
34
|
+
lib/rufus-runner.rb
|
35
|
+
lib/rufus-runner/tracking_scheduler.rb
|
36
|
+
lib/rufus-runner/tracking_scheduler/job_runner.rb
|
37
|
+
lib/rufus-runner/tracking_scheduler/threading_job_runner.rb
|
38
|
+
lib/rufus-runner/tracking_scheduler/forking_job_runner.rb
|
39
|
+
lib/rufus-runner/version.rb
|
40
|
+
rufus-runner.gemspec
|
41
|
+
)
|
42
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
43
|
+
gem.test_files = gem.files.grep(%r{^spec/})
|
44
|
+
gem.require_paths = ["lib"]
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rufus-runner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Julien Letessier
|
8
|
+
- Chuck Callebs
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-08-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: eventmachine
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rufus-scheduler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 2.0.23
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 2.0.23
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '2'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rb-inotify
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rb-fsevent
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rb-fchange
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: terminal-notifier-guard
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: pry
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: pry-nav
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: rspec-instafail
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
description: Wrapper process around rufus-scheduler
|
169
|
+
email:
|
170
|
+
- julien.letessier@gmail.com
|
171
|
+
- chuck@callebs.io
|
172
|
+
executables:
|
173
|
+
- rufus-runner
|
174
|
+
extensions: []
|
175
|
+
extra_rdoc_files: []
|
176
|
+
files:
|
177
|
+
- LICENSE.txt
|
178
|
+
- README.md
|
179
|
+
- bin/rufus-runner
|
180
|
+
- lib/rufus-runner.rb
|
181
|
+
- lib/rufus-runner/tracking_scheduler.rb
|
182
|
+
- lib/rufus-runner/tracking_scheduler/forking_job_runner.rb
|
183
|
+
- lib/rufus-runner/tracking_scheduler/job_runner.rb
|
184
|
+
- lib/rufus-runner/tracking_scheduler/threading_job_runner.rb
|
185
|
+
- lib/rufus-runner/version.rb
|
186
|
+
- rufus-runner.gemspec
|
187
|
+
homepage: http://github.com/ccallebs/rufus-runner
|
188
|
+
licenses:
|
189
|
+
- MIT
|
190
|
+
metadata: {}
|
191
|
+
post_install_message:
|
192
|
+
rdoc_options: []
|
193
|
+
require_paths:
|
194
|
+
- lib
|
195
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
201
|
+
requirements:
|
202
|
+
- - ">="
|
203
|
+
- !ruby/object:Gem::Version
|
204
|
+
version: '0'
|
205
|
+
requirements: []
|
206
|
+
rubyforge_project:
|
207
|
+
rubygems_version: 2.4.8
|
208
|
+
signing_key:
|
209
|
+
specification_version: 4
|
210
|
+
summary: Wrapper process around rufus-scheduler
|
211
|
+
test_files: []
|