scheduler_daemon 0.5.1 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -0
- data/Gemfile.lock +36 -0
- data/README.markdown +83 -28
- data/Rakefile +39 -31
- data/VERSION +1 -1
- data/bin/scheduler_daemon +59 -0
- data/lib/loader/scheduler_loader.rb +12 -0
- data/lib/scheduler_daemon.rb +2 -0
- data/lib/scheduler_daemon/base.rb +149 -0
- data/lib/scheduler_daemon/command_line_args_to_hash.rb +47 -0
- data/lib/scheduler_daemon/exception_handler.rb +30 -0
- data/{generators → lib/scheduler_daemon/rails/generators}/scheduler/USAGE +0 -0
- data/lib/scheduler_daemon/rails/generators/scheduler/scheduler_generator.rb +16 -0
- data/lib/scheduler_daemon/rails/generators/scheduler/templates/README +11 -0
- data/lib/scheduler_daemon/rails/generators/scheduler/templates/lib/scheduled_tasks/session_cleaner_task.rb +29 -0
- data/lib/scheduler_daemon/rails/generators/scheduler_task/scheduler_task_generator.rb +17 -0
- data/{generators → lib/scheduler_daemon/rails/generators}/scheduler_task/templates/README +1 -1
- data/lib/scheduler_daemon/rails/generators/scheduler_task/templates/scheduled_tasks/example_task.rb +19 -0
- data/lib/scheduler_daemon/rails/railtie.rb +9 -0
- data/{generators/scheduler/templates/lib/scheduler → lib/scheduler_daemon}/scheduler_task.rb +17 -8
- data/scheduler_daemon.gemspec +58 -35
- data/spec/command_line_args_to_hash_spec.rb +26 -0
- data/spec/scheduled_tasks/session_cleaner_task_spec.rb +11 -7
- data/spec/scheduler_spec.rb +18 -7
- data/spec/spec_helper.rb +16 -0
- metadata +177 -50
- data/.gitignore +0 -1
- data/CHANGES +0 -10
- data/generators/scheduler/scheduler_generator.rb +0 -25
- data/generators/scheduler/templates/README +0 -8
- data/generators/scheduler/templates/bin/boot.rb +0 -10
- data/generators/scheduler/templates/bin/scheduler_daemon.rb +0 -25
- data/generators/scheduler/templates/lib/scheduled_tasks/session_cleaner_task.rb +0 -21
- data/generators/scheduler/templates/lib/scheduler.rb +0 -90
- data/generators/scheduler/templates/lib/scheduler/exception_handler.rb +0 -12
- data/generators/scheduler/templates/lib/scheduler/hijack_puts.rb +0 -8
- data/generators/scheduler_task/scheduler_task_generator.rb +0 -11
- data/generators/scheduler_task/templates/scheduled_tasks/example_task.rb +0 -10
- data/init.rb +0 -1
- data/install.rb +0 -1
- data/lib/scheduler.rb +0 -2
- data/spec/README +0 -1
- data/uninstall.rb +0 -1
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
scheduler_daemon (1.1.0)
|
5
|
+
activesupport
|
6
|
+
chronic (>= 0.2.0)
|
7
|
+
chronic (>= 0.2.0)
|
8
|
+
daemons (>= 1.0.10)
|
9
|
+
daemons (>= 1.0.10)
|
10
|
+
eventmachine (>= 0.12.8)
|
11
|
+
eventmachine (>= 0.12.8)
|
12
|
+
rufus-scheduler (>= 2.0.1)
|
13
|
+
rufus-scheduler (>= 2.0.1)
|
14
|
+
scheduler_daemon
|
15
|
+
|
16
|
+
GEM
|
17
|
+
remote: http://rubygems.org/
|
18
|
+
specs:
|
19
|
+
activesupport (3.0.6)
|
20
|
+
chronic (0.3.0)
|
21
|
+
daemons (1.1.2)
|
22
|
+
eventmachine (0.12.10)
|
23
|
+
rufus-scheduler (2.0.8)
|
24
|
+
tzinfo (>= 0.3.23)
|
25
|
+
tzinfo (0.3.26)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
activesupport
|
32
|
+
chronic (>= 0.2.0)
|
33
|
+
daemons (>= 1.0.10)
|
34
|
+
eventmachine (>= 0.12.8)
|
35
|
+
rufus-scheduler (>= 2.0.1)
|
36
|
+
scheduler_daemon!
|
data/README.markdown
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
Scheduler Daemon
|
2
2
|
================
|
3
3
|
|
4
|
-
Rails
|
4
|
+
Rails 3+ compatible scheduler daemon (see branches for older versions).
|
5
|
+
|
6
|
+
Replaces cron/rake pattern of periodically running rake tasks
|
5
7
|
to perform maintenance tasks in Rails apps. Scheduler Daemon is made specifically for your Rails app,
|
6
8
|
and only loads the environment once, no matter how many tasks run.
|
7
9
|
|
@@ -10,71 +12,128 @@ What's so great about it? Well, I'm glad you asked!
|
|
10
12
|
- Only loads your Rails environment once on daemon start, not every time a task is run
|
11
13
|
- Allows you to easily deploy the scheduled tasks with your Rails app instead of depending on an
|
12
14
|
administrator to update crontab
|
15
|
+
- Can be installed as a gem or a plugin (I suggest gem)
|
13
16
|
- It doesn't use rake or cron!
|
14
17
|
- Gets you up and running with your own daemon in under 2 minutes
|
18
|
+
- Specially designed to work with your rails app!
|
15
19
|
|
16
20
|
Setup
|
17
21
|
=====
|
18
22
|
|
19
|
-
Install
|
23
|
+
Install as a gem or plugin.
|
20
24
|
|
21
|
-
|
25
|
+
As a gem, the old-fashioned way:
|
26
|
+
|
27
|
+
gem install scheduler_daemon
|
22
28
|
|
23
|
-
|
29
|
+
As a gem with bundler, add to your ./Gemfile:
|
24
30
|
|
25
|
-
gem
|
31
|
+
gem 'scheduler_daemon'
|
32
|
+
|
33
|
+
I pretty much assume you chose this option below and prefix most commands with "bundle exec"
|
26
34
|
|
27
|
-
|
35
|
+
As a plugin: (might be awkward to call the binary to start up the daemon...)
|
36
|
+
|
37
|
+
script/plugin install git://github.com/ssoroka/scheduler_daemon.git
|
38
|
+
# Install required gems
|
39
|
+
gem install daemons rufus-scheduler eventmachine chronic -s http://gemcutter.org
|
28
40
|
|
29
|
-
|
41
|
+
Optionally generate the default scheduler daemon task for your rails app:
|
30
42
|
|
31
|
-
|
43
|
+
script/rails generate scheduler_task MyNewTask
|
32
44
|
|
33
|
-
|
45
|
+
which will create an task named:
|
34
46
|
|
35
|
-
|
47
|
+
scheduled_tasks/my_new_task.rb
|
36
48
|
|
37
49
|
Usage
|
38
50
|
=====
|
39
51
|
|
40
52
|
generate a new scheduled task:
|
41
53
|
|
42
|
-
script/generate scheduler_task MyTaskName
|
54
|
+
script/rails generate scheduler_task MyTaskName
|
43
55
|
|
56
|
+
If you have problems with that, the template for new tasks is in the gem under:
|
57
|
+
|
58
|
+
lib/scheduler_daemon/rails/generators/scheduler_task/templates/scheduled_tasks/example_task.rb
|
59
|
+
|
60
|
+
you can always copy it and make modifications, or see "Manually create tasks" below.
|
44
61
|
|
45
62
|
Tasks support their own special DSL; commands are:
|
46
63
|
|
47
64
|
environments :production, :staging # run only in environments listed. (:all by default)
|
48
|
-
every '1d' # run
|
49
|
-
every '1d', :first_at => Chronic.parse("2 am") # run
|
50
|
-
at Cronic.parse('5 pm') # run once at 5 pm
|
51
|
-
|
65
|
+
every '1d' # run every day
|
66
|
+
every '1d', :first_at => Chronic.parse("2 am") # run every day, starting at 2 am (see caveat below)
|
67
|
+
at Cronic.parse('5 pm') # run *once* at 5 pm today
|
68
|
+
# (relative to scheduler start/restart time )
|
69
|
+
# (happens every time scheduler starts/restarts)
|
70
|
+
# (see caveat below )
|
71
|
+
cron '* 4 * * *' # cron style (run every 4 am)
|
52
72
|
in '30s' # run once, 30 seconds from scheduler start/restart
|
53
73
|
|
54
74
|
fire up the daemon in console mode to test it out
|
55
75
|
|
56
|
-
|
76
|
+
bundle exec scheduler_daemon run
|
57
77
|
|
58
|
-
|
78
|
+
For production environments, add the daemon to the system start-up, and
|
59
79
|
capistrano deploy scripts, etc. Something like:
|
60
80
|
|
61
|
-
RAILS_ENV=production
|
81
|
+
export RAILS_ENV=production
|
82
|
+
bundle exec scheduler_daemon start
|
62
83
|
|
63
|
-
|
84
|
+
Selectively run tasks like so:
|
64
85
|
|
65
|
-
|
86
|
+
bundle exec scheduler_daemon start -- --only=task_name1,task_name2 --except=not_me
|
87
|
+
|
88
|
+
Manually create tasks
|
89
|
+
=====================
|
90
|
+
|
91
|
+
If you don't want to use this gem with Rails, you can manually create tasks in a scheduled_tasks/ subdirectory and start the daemon with --skip-rails (though it'll figure it out anyway if there's no config/environment.rb file in the launch directory or --dir=/path)
|
92
|
+
|
93
|
+
Here's an example task file.
|
94
|
+
|
95
|
+
class CleanUpTask < Scheduler::SchedulerTask
|
96
|
+
every '2m'
|
97
|
+
|
98
|
+
def run
|
99
|
+
do_something
|
100
|
+
log("I've done things")
|
101
|
+
end
|
102
|
+
end
|
66
103
|
|
67
104
|
Specs
|
68
105
|
=====
|
69
106
|
|
70
|
-
|
71
|
-
|
72
|
-
See spec/README for more information
|
107
|
+
See the spec for session cleaner for an idea on how to write specs for your tasks
|
73
108
|
|
74
109
|
To Do
|
75
110
|
=====
|
76
111
|
|
77
|
-
|
112
|
+
Looking for suggestions!
|
113
|
+
|
114
|
+
Send requests to ssoroka78@gmail.com or on twitter, @ssoroka
|
115
|
+
|
116
|
+
Bugs
|
117
|
+
====
|
118
|
+
|
119
|
+
Submit bugs here http://github.com/ssoroka/scheduler_daemon/issues
|
120
|
+
|
121
|
+
Caveats
|
122
|
+
=======
|
123
|
+
|
124
|
+
When using the cronic gem to parse dates, be careful of how it interprets your date,
|
125
|
+
for example:
|
126
|
+
|
127
|
+
every '24h', :first_at => Chronic.parse('noon')
|
128
|
+
|
129
|
+
will be once a day at noon, but the first time the server starts up (or restarts), noon
|
130
|
+
is relative to the current time of day. Before lunch, and it's in the future. If the
|
131
|
+
daemon starts up after lunch, the date is in the past, *and the task is immediately run*
|
132
|
+
because it thinks it missed its last execution time. Depending on what your task is,
|
133
|
+
this may or may not be a problem. If you always want the date to resolve in the future
|
134
|
+
with terms like "noon", "3 am" and "midnight", prepend "next" to it. ie:
|
135
|
+
|
136
|
+
every '24h', :first_at => Chronic.parse('next noon')
|
78
137
|
|
79
138
|
Author
|
80
139
|
======
|
@@ -85,7 +144,3 @@ Steven Soroka
|
|
85
144
|
* [My Github repo](http://github.com/ssoroka)
|
86
145
|
* [My blog](http://blog.stevensoroka.ca)
|
87
146
|
|
88
|
-
Thanks
|
89
|
-
======
|
90
|
-
|
91
|
-
Special thanks to [Goldstar](http://www.goldstar.com) for sponsoring the plugin and promoting open-sourcesness.
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "scheduler_daemon"
|
8
|
-
gem.summary = %Q{Rails
|
8
|
+
gem.summary = %Q{Rails 3 compatible scheduler daemon. Replaces cron/rake pattern of periodically running rake tasks
|
9
9
|
to perform maintenance tasks in Rails apps. Scheduler Daemon is made specifically for your Rails app,
|
10
10
|
and only loads the environment once, no matter how many tasks run.
|
11
11
|
|
@@ -17,6 +17,8 @@ begin
|
|
17
17
|
- It doesn't use rake or cron!
|
18
18
|
- Gets you up and running with your own daemon in under 2 minutes
|
19
19
|
}
|
20
|
+
gem.version = File.read('VERSION').chomp
|
21
|
+
gem.description = 'a Rails 2.3, Rails 3, and Ruby compatible scheduler daemon. Replaces cron/rake pattern of periodically running rake tasks to perform maintenance tasks, only loading the environment ONCE.'
|
20
22
|
gem.email = "ssoroka78@gmail.com"
|
21
23
|
gem.homepage = "http://github.com/ssoroka/scheduler_daemon"
|
22
24
|
gem.authors = ["Steven Soroka"]
|
@@ -24,6 +26,12 @@ begin
|
|
24
26
|
gem.add_dependency('daemons', '>= 1.0.10')
|
25
27
|
gem.add_dependency('rufus-scheduler', '>= 2.0.1')
|
26
28
|
gem.add_dependency('chronic', '>= 0.2.0')
|
29
|
+
|
30
|
+
gem.executables = ['scheduler_daemon']
|
31
|
+
|
32
|
+
everything_from_dirs = %w(bin lib spec)
|
33
|
+
gem.files = everything_from_dirs.map{|d| Dir["#{d}/**/*"] }.flatten
|
34
|
+
gem.files += Dir['*'] - (everything_from_dirs + ['pkg'])
|
27
35
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
28
36
|
end
|
29
37
|
|
@@ -31,33 +39,33 @@ rescue LoadError
|
|
31
39
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
32
40
|
end
|
33
41
|
|
34
|
-
require 'spec/rake/spectask'
|
35
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
36
|
-
|
37
|
-
|
38
|
-
end
|
39
|
-
|
40
|
-
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
task :default => :spec
|
48
|
-
|
49
|
-
require 'rake/rdoctask'
|
50
|
-
Rake::RDocTask.new do |rdoc|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
|
42
|
+
# require 'spec/rake/spectask'
|
43
|
+
# Spec::Rake::SpecTask.new(:spec) do |spec|
|
44
|
+
# spec.libs << 'lib' << 'spec'
|
45
|
+
# spec.spec_files = FileList['spec/**/*_spec.rb']
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# Spec::Rake::SpecTask.new(:rcov) do |spec|
|
49
|
+
# spec.libs << 'lib' << 'spec'
|
50
|
+
# spec.pattern = 'spec/**/*_spec.rb'
|
51
|
+
# spec.rcov = true
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
#
|
55
|
+
# task :default => :spec
|
56
|
+
#
|
57
|
+
# require 'rake/rdoctask'
|
58
|
+
# Rake::RDocTask.new do |rdoc|
|
59
|
+
# if File.exist?('VERSION.yml')
|
60
|
+
# config = YAML.load(File.read('VERSION.yml'))
|
61
|
+
# version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
62
|
+
# else
|
63
|
+
# version = ""
|
64
|
+
# end
|
65
|
+
#
|
66
|
+
# rdoc.rdoc_dir = 'rdoc'
|
67
|
+
# rdoc.title = "scheduler_daemon #{version}"
|
68
|
+
# rdoc.rdoc_files.include('README*')
|
69
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
70
|
+
# end
|
71
|
+
#
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
1.1.1
|
@@ -0,0 +1,59 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This file launches the scheduler as a daemon.
|
3
|
+
# USAGE:
|
4
|
+
#
|
5
|
+
# scheduler_daemon run # start the daemon and stay on top
|
6
|
+
# scheduler_daemon start # start the daemon and stay on top
|
7
|
+
# scheduler_daemon stop # stop all instances of the application
|
8
|
+
# scheduler_daemon restart # stop all instances and restart them afterwards
|
9
|
+
#
|
10
|
+
# options can be passed to the scheduler like so:
|
11
|
+
#
|
12
|
+
# scheduler_daemon start -- --except=session_cleaner
|
13
|
+
#
|
14
|
+
# options can be passed to the daemon:
|
15
|
+
#
|
16
|
+
# scheduler_daemon start --dir=/my/rails/root/
|
17
|
+
#
|
18
|
+
# see README for more info
|
19
|
+
require 'rubygems'
|
20
|
+
require 'daemons'
|
21
|
+
require 'scheduler_daemon/command_line_args_to_hash'
|
22
|
+
|
23
|
+
# arguments to pass to the daemon launcher
|
24
|
+
def launch_args(options = {})
|
25
|
+
params = options.map{|k,v| "--#{k}=#{v}"}
|
26
|
+
if params.empty?
|
27
|
+
ARGV
|
28
|
+
else
|
29
|
+
args = ARGV.dup
|
30
|
+
args << '--' unless args.include?('--')
|
31
|
+
args + params
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# app arguments
|
36
|
+
app_args = {}
|
37
|
+
# only take args after the '--' arg.
|
38
|
+
if separator_index = ARGV.index('--')
|
39
|
+
app_args = CommandLineArgsToHash.parse(ARGV[separator_index+1..-1])
|
40
|
+
end
|
41
|
+
|
42
|
+
app_args[:dir] ||= Dir.pwd
|
43
|
+
app_args[:pid_dir] ||= File.expand_path(File.join(app_args[:dir], 'log'))
|
44
|
+
scheduler = File.join(File.dirname(__FILE__), %w(.. lib loader scheduler_loader.rb))
|
45
|
+
|
46
|
+
raise "#{pid_dir} does not exist" unless File.exist?(app_args[:pid_dir])
|
47
|
+
|
48
|
+
app_options = {
|
49
|
+
:app_name => 'scheduler_daemon',
|
50
|
+
:ARGV => launch_args(app_args),
|
51
|
+
:dir_mode => :normal,
|
52
|
+
:dir => app_args[:pid_dir],
|
53
|
+
:multiple => false,
|
54
|
+
:backtrace => true,
|
55
|
+
:log_output => true,
|
56
|
+
:monitor => true
|
57
|
+
}
|
58
|
+
|
59
|
+
Daemons.run(scheduler, app_options)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This file loads the rails environment and starts the scheduler.
|
3
|
+
# do not use it directly unless you don't intend for the scheduler to run as a daemon.
|
4
|
+
require 'scheduler_daemon/command_line_args_to_hash'
|
5
|
+
args = CommandLineArgsToHash.parse(ARGV)
|
6
|
+
daemons_lib_dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
|
7
|
+
|
8
|
+
Dir.chdir(args[:dir])
|
9
|
+
|
10
|
+
require File.join(daemons_lib_dir, 'scheduler_daemon', 'base')
|
11
|
+
|
12
|
+
Scheduler::Base.new(args)
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'rufus/scheduler'
|
3
|
+
begin
|
4
|
+
require 'active_support/hash_with_indifferent_access'
|
5
|
+
rescue LoadError
|
6
|
+
begin
|
7
|
+
require 'active_support/core_ext/hash'
|
8
|
+
rescue LoadError
|
9
|
+
puts "can't load activesupport gem not loaded"
|
10
|
+
raise $!
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'scheduler_daemon/scheduler_task'
|
15
|
+
require 'scheduler_daemon/exception_handler'
|
16
|
+
require 'scheduler_daemon/command_line_args_to_hash'
|
17
|
+
|
18
|
+
module Scheduler
|
19
|
+
class Base
|
20
|
+
attr_reader :tasks, :options, :env_name
|
21
|
+
|
22
|
+
# :root_dir is a required option, because the scheduler likely has no idea what the original
|
23
|
+
# root directory was after the process was daemonized (which changes the current directory)
|
24
|
+
# :silent
|
25
|
+
# doesn't output anything to STDOUT or logs.
|
26
|
+
# :root_dir
|
27
|
+
# root dir of the application.
|
28
|
+
# :only
|
29
|
+
# load only tasks in this list
|
30
|
+
# :except
|
31
|
+
# load all tasks except ones in this list
|
32
|
+
# :env_name
|
33
|
+
# if used without rails, you can manually set something in place of the environment name
|
34
|
+
def initialize(opts = {}, command_line_args = [])
|
35
|
+
@options = ::HashWithIndifferentAccess.new(opts)
|
36
|
+
@options.merge!(CommandLineArgsToHash.parse(command_line_args, :array_args => ['only', 'except']))
|
37
|
+
@options['only'] ||= []
|
38
|
+
@options['except'] ||= []
|
39
|
+
@env_name = @options['env_name'] || 'scheduler'
|
40
|
+
@rufus_scheduler = nil
|
41
|
+
@tasks = []
|
42
|
+
|
43
|
+
log("initialized with settings: #{@options.inspect}")
|
44
|
+
|
45
|
+
if !@options['skip_init']
|
46
|
+
load_rails_env
|
47
|
+
load_tasks
|
48
|
+
run_scheduler
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# registers a task class with the scheduler
|
53
|
+
def register_task(task)
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def load_rails_env
|
58
|
+
if File.exists?('config/environment.rb') && !@options['skip_rails']
|
59
|
+
log("loading rails environment")
|
60
|
+
require 'config/environment'
|
61
|
+
@env_name = ::Rails.env
|
62
|
+
end
|
63
|
+
rescue
|
64
|
+
log("Error loading rails environment; #{$!.class.name}: #{$!.message}")
|
65
|
+
raise $!
|
66
|
+
end
|
67
|
+
|
68
|
+
# time redefines itself with a faster implementation, since it gets called a lot.
|
69
|
+
def time
|
70
|
+
if Time.respond_to?(:zone) && Time.zone
|
71
|
+
self.class.send(:define_method, :time) { Time.zone.now.to_s }
|
72
|
+
else
|
73
|
+
self.class.send(:define_method, :time) { Time.now.to_s }
|
74
|
+
end
|
75
|
+
time
|
76
|
+
end
|
77
|
+
|
78
|
+
def log(*args)
|
79
|
+
return if @options[:silent]
|
80
|
+
Kernel::puts(%([#{time}] #{args.join("\n")}))
|
81
|
+
end
|
82
|
+
alias :puts :log
|
83
|
+
|
84
|
+
def run_scheduler
|
85
|
+
if defined?(::Rails)
|
86
|
+
log "Starting Scheduler in #{::Rails.env}"
|
87
|
+
else
|
88
|
+
log "Starting Scheduler"
|
89
|
+
end
|
90
|
+
|
91
|
+
$daemon_scheduler = self
|
92
|
+
|
93
|
+
EventMachine::run {
|
94
|
+
@rufus_scheduler = Rufus::Scheduler::EmScheduler.start_new
|
95
|
+
|
96
|
+
def @rufus_scheduler.handle_exception(job, exception)
|
97
|
+
msg = "[#{env_name}] scheduler job #{job.job_id} (#{job.tags * ' '}) caught exception #{exception.inspect}"
|
98
|
+
log msg
|
99
|
+
log exception.backtrace.join("\n")
|
100
|
+
Scheduler::ExceptionHandler.handle_exception(exception, job, message)
|
101
|
+
end
|
102
|
+
|
103
|
+
def @rufus_scheduler.daemon_scheduler
|
104
|
+
$daemon_scheduler
|
105
|
+
end
|
106
|
+
|
107
|
+
# This is where the magic happens. tasks in scheduled_tasks/*.rb are loaded up.
|
108
|
+
tasks.each do |task|
|
109
|
+
if task.should_run_in_current_environment?(env_name)
|
110
|
+
task.add_to(@rufus_scheduler)
|
111
|
+
else
|
112
|
+
log "[#{env_name}] #{task} not configured to run; skipping."
|
113
|
+
end
|
114
|
+
end
|
115
|
+
}
|
116
|
+
end
|
117
|
+
|
118
|
+
def load_tasks
|
119
|
+
tasks_to_run.each{|f|
|
120
|
+
begin
|
121
|
+
unless options[:only].any? && options[:only].all?{|m| f !~ Regexp.new(Regexp.escape(m)) }
|
122
|
+
require f
|
123
|
+
filename = f.split('/').last.split('.').first
|
124
|
+
log "Loading task #{filename}..."
|
125
|
+
@tasks << filename.camelcase.constantize # "path/newsfeed_task.rb" => NewsfeedTask
|
126
|
+
end
|
127
|
+
rescue Exception => e
|
128
|
+
msg = "Error loading task #{filename}: #{e.class.name}: #{e.message}"
|
129
|
+
log msg
|
130
|
+
log e.backtrace.join("\n")
|
131
|
+
Scheduler::ExceptionHandler.handle_exception(e, nil, msg)
|
132
|
+
end
|
133
|
+
}
|
134
|
+
end
|
135
|
+
|
136
|
+
def tasks_to_run
|
137
|
+
task_files = Dir[File.join(%w(scheduled_tasks *.rb))]# + File.join(%w(lib scheduled_tasks *.rb))
|
138
|
+
|
139
|
+
if options[:only].any?
|
140
|
+
task_files.reject!{|f| options[:only].all?{|m| f !~ Regexp.new(Regexp.escape(m))}}
|
141
|
+
end
|
142
|
+
|
143
|
+
if options[:except].any?
|
144
|
+
task_files.reject!{|f| options[:except].any?{|m| f =~ Regexp.new(Regexp.escape(m))}}
|
145
|
+
end
|
146
|
+
task_files
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|