crondonkulous 1.0.0

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.
@@ -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