crondonkulous 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ === 1.0.0 2009-08-18
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
@@ -0,0 +1,15 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.rdoc
4
+ Rakefile
5
+ lib/crondonkulous.rb
6
+ lib/crondonkulous/recipes.rb
7
+ rails_generators/crondonkulous_generator.rb
8
+ rails_generators/templates/crondonkulous.rake
9
+ rails_generators/templates/crontab.erb
10
+ rails_generators/templates/readme.txt
11
+ script/console
12
+ script/destroy
13
+ script/generate
14
+ test/test_crondonkulous.rb
15
+ test/test_helper.rb
@@ -0,0 +1,74 @@
1
+ = crondonkulous
2
+
3
+ * http://github.com/bokmann/crondonkulous
4
+
5
+ == DESCRIPTION:
6
+
7
+ Ever need to have process run regularly for your rails app? Ever want to use cron as the answer? Sure you have! So lets get it done.
8
+
9
+ It sounds pretty easy... use cron to automate the periodic execution of some rake tasks... but in practice we run into a couple of problems:
10
+
11
+ * Keeping the cron tasks in sync with your capistrano deploys
12
+ * preventing the cron tasks from running while you are deploying/migrating
13
+ * keeping the cron tasks from stepping on each other if they are taking longer than expected to run
14
+ * having cron logging output intermingled with logging from your controllers
15
+
16
+ Ever have any of these problems? I know I have. So lets solve them once and for all, and bundle it into a gem with some reusable conventions. Enter Crondonkulous!
17
+
18
+ == Here's what you get:
19
+ * a crontab file with all the silly little syntax you need to specify tasks for:
20
+ * every minute
21
+ * every 5 minutes
22
+ * every 15 minutes
23
+ * every hour
24
+ * every day
25
+ * every week
26
+ * every month
27
+ * a crondonkulous.rake template that separates logging out of your controller's log file, with a sane naming convention for logs
28
+ * a lockfile, so that rake tasks invoked with cron won't start if there is another one running (and you specify the number of times to retry)
29
+ * capistrano tasks that:
30
+ * stop the cronned rake tasks while deploying
31
+ * wait until any running ones are done before continuing the deploy
32
+ * load in any new cron entries when the webapp restarts.
33
+
34
+
35
+ == REQUIREMENTS:
36
+
37
+ * Its a gem for rails, so.. uh, all of that stuff.
38
+ * a capistrano deploy (will gladly accept patches for vlad)
39
+ * a server running cron that allows crontab entries by user
40
+ * also relies on the lockfile gem
41
+
42
+ == INSTALL:
43
+
44
+ * sudo gem install bokmann-crondonkulous
45
+ * ./script/generate crondonkulous
46
+ * follow the instructions to modify the files it puts in your project
47
+
48
+ == HISTORY:
49
+ A couple of years ago I wrote the 'automate repeatable tasks' recipe for the book Advanced Rails Recipes from Pragmatic Bookshelf. Some of these ideas are represented there, but they have evolved a lot as I have added better integration with capistrano, reliance on the lockfile gem, etc.
50
+
51
+ == LICENSE:
52
+
53
+ (The MIT License)
54
+
55
+ Copyright (c) 2009 CodeSherpas Inc.
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ 'Software'), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
71
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
72
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
73
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
74
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,20 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rcov/rcovtask'
4
+ require 'shoulda/tasks'
5
+
6
+ begin
7
+ require 'jeweler'
8
+ Jeweler::Tasks.new do |gemspec|
9
+ gemspec.name = "crondonkulous"
10
+ gemspec.summary = "A generator and conventions for using cron with rake tasks in a rails application."
11
+ gemspec.description = "A generator and conventions for using cron with rake tasks in a rails application."
12
+ gemspec.email = "dbock@codesherpas.com"
13
+ gemspec.homepage = "http://github.com/bokmann/crondonkulous"
14
+ gemspec.authors = ["David Bock"]
15
+ gemspec.add_dependency('lockfile', '>= 1.4.0')
16
+
17
+ end
18
+ rescue LoadError
19
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
20
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.0
@@ -0,0 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ module Crondonkulous
5
+ VERSION = '1.0.0'
6
+ end
@@ -0,0 +1,31 @@
1
+ Capistrano::Configuration.instance.load do
2
+
3
+ #TODO wouldn't it be awesome if the deploy would wait for the crondonkulous rakefile to unlock?
4
+ set :cron_user, nil
5
+
6
+ before "deploy:update_code", "crondonkulous:clear_crontab"
7
+ after "deploy:finalize_update", "crondonkulous:load_crontab"
8
+
9
+ namespace :crondonkulous do
10
+
11
+ task :load_crontab do
12
+ require 'erb'
13
+ tempfile = "#{current_path}/log/crontab.rendered"
14
+ crontab = ERB.new(File.read("config/crontab.erb")).result(binding)
15
+ put crontab, "#{tempfile}"
16
+ u = cron_user || user
17
+ sudo "crontab -u #{u} #{tempfile}"
18
+ end
19
+
20
+ task :clear_crontab do
21
+ begin
22
+ u = cron_user || user
23
+ sudo "crontab -r -u #{u}"
24
+ rescue
25
+ end
26
+ sleep 30 #TODO I want to make this safer, but lets give stuff a chance to finish...
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,9 @@
1
+ class CrondonkulousGenerator < Rails::Generator::Base
2
+ def manifest
3
+ record do |m|
4
+ m.file('crondonkulous.rake', 'lib/tasks/crondonkulous.rake')
5
+ m.file('crontab.erb', 'config/crontab.erb')
6
+ m.readme('readme.txt')
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,65 @@
1
+ namespace :crondonkulous do
2
+
3
+ desc "Your description here"
4
+ task :every_minute => :environment do
5
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_minute.log", 0) do
6
+ #your code here
7
+ end
8
+ end
9
+
10
+ desc "Your description here"
11
+ task :every_5_minutes => :environment do
12
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_5_minutes.log", 0) do
13
+ #your code here
14
+ end
15
+ end
16
+
17
+ desc "Your description here"
18
+ task :every_15_minutes => :environment do
19
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_15_minutes.log", 0) do
20
+ #your code here
21
+ end
22
+ end
23
+
24
+ desc "Your description here"
25
+ task :every_hour => :environment do
26
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_hour.log", 0) do
27
+ #your code here
28
+ end
29
+ end
30
+
31
+ desc "Your description here"
32
+ task :every_week => :environment do
33
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_week.log", 0) do
34
+ #your code here
35
+ end
36
+ end
37
+
38
+ desc "Your description here"
39
+ task :every_month => :environment do
40
+ crondonkulous_wrapper(RAILS_ROOT + "/log/every_month.log", 0) do
41
+ #your code here
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ def crondonkulous_wrapper(logfile, retries = 0)
48
+ ActiveRecord::Base.logger = Logger.new(logfile)
49
+ ActiveRecord::Base.logger.info "*-"*38
50
+ ActiveRecord::Base.logger.info "** Invoked at #{Time.now}"
51
+
52
+ begin
53
+ Lockfile.new(RAILS_ROOT + "/log/crondonkulous.lock", :retries => retries) do
54
+ yield
55
+ end
56
+ rescue Lockfile::MaxTriesLockError => e
57
+ ActiveRecord::Base.logger.info "Another process is running. Exiting gracefully."
58
+ rescue
59
+ ActiveRecord::Base.logger.error $!
60
+ ensure
61
+ ActiveRecord::Base.logger.info "** Completed at #{Time.now}"
62
+ ActiveRecord::Base.logger.close
63
+ end
64
+ end
65
+
@@ -0,0 +1,7 @@
1
+ */1 * * * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_minute
2
+ #*/5 * * * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_5_minutes
3
+ #*/15 * * * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_15_minutes
4
+ 01 * * * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_hour
5
+ 02 0 * * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_day
6
+ 03 0 * * 1 rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_week
7
+ 04 0 1 * * rake -f <%= current_path %>/Rakefile RAILS_ENV=<%= rails_env %> crondonkulous:every_month
@@ -0,0 +1,24 @@
1
+ Thanks for installing Crondonkulous! There are still some things you have to do:
2
+
3
+ 1) open up your config/deploy.rb used by capistrano, and add this line to the top:
4
+
5
+ require 'crondonkulous/recipes.rb'
6
+
7
+ Our recipes hook into your deploy to load the crontab.
8
+
9
+ 2) Add this line to your config/environment.rb file:
10
+
11
+ config.gem "lockfile"
12
+
13
+ 3) uncomment the cron tasks you want to run in the config/crontab.erb file.
14
+
15
+ 4) add your own code to the lib/tasks/crondonkulous.rake file.
16
+
17
+ 5) optionally, you can add this line to your config/deploy.rb:
18
+
19
+ set :cron_user, "username"
20
+
21
+ If you don't set this, crondonkulous will default to the deploying user.
22
+
23
+ Have Fun!
24
+ - Your friends at CodeSherpas
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/crondonkulous.rb'}"
9
+ puts "Loading crondonkulous gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class TestCrondonkulous < Test::Unit::TestCase
4
+
5
+ def setup
6
+ end
7
+
8
+ def test_truth
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/crondonkulous'
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crondonkulous
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - David Bock
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-11 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: lockfile
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.4.0
24
+ version:
25
+ description: A generator and conventions for using cron with rake tasks in a rails application.
26
+ email: dbock@codesherpas.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - History.txt
35
+ - Manifest.txt
36
+ - README.rdoc
37
+ - Rakefile
38
+ - VERSION
39
+ - lib/crondonkulous.rb
40
+ - lib/crondonkulous/recipes.rb
41
+ - rails_generators/crondonkulous_generator.rb
42
+ - rails_generators/templates/crondonkulous.rake
43
+ - rails_generators/templates/crontab.erb
44
+ - rails_generators/templates/readme.txt
45
+ - script/console
46
+ - script/destroy
47
+ - script/generate
48
+ - test/test_crondonkulous.rb
49
+ - test/test_helper.rb
50
+ has_rdoc: true
51
+ homepage: http://github.com/bokmann/crondonkulous
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options:
56
+ - --charset=UTF-8
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: A generator and conventions for using cron with rake tasks in a rails application.
78
+ test_files:
79
+ - test/test_crondonkulous.rb
80
+ - test/test_helper.rb