Crontab grows larger and larger with every new cleanup/maintence task…
... 0 0 1 * * cd ~/apps/my_app/current && RAILS_ENV=production rake summary:weekly_update >> ~/apps/my_app/current/log/summary_weekly_update.log 0 0 7 * * cd ~/apps/my_app/current && RAILS_ENV=production rake summary:weekly_update >> ~/apps/my_app/current/log/summary_weekly_update.log 0 0 14 * * cd ~/apps/my_app/current && RAILS_ENV=production rake summary:weekly_update >> ~/apps/my_app/current/log/summary_weekly_update.log 0 0 21 * * cd ~/apps/my_app/current && RAILS_ENV=production rake summary:weekly_update >> ~/apps/my_app/current/log/summary_weekly_update.log ... echo 'crontab sucks...'
This is not DRY, so we fix it…
Cron calls “rake night” every night and night takes care of the rest…
#redirect and append puts to the logfile def logging_to(path) FileUtils.touch([path]) $stdout = File.new(path,'a+') yield $stdout = STDOUT end #use DRY to simulate a dry run #uses hoptoad for error recording(better than exception notifier...), get it @ hoptoad.com def invoke_and_log_task(name) begin logging_to "log/#{name.gsub(':','_')}.log" do if ENV['DRY'] puts "dry-running #{name}" else Rake::Task[name].invoke end end rescue Exception => e HoptoadNotifier.notify( :error_class => "Nightly #{name} Error #{e.class}", :error_message => "#{e.message}" ) end end desc "Runs maintains tasks at night" task :night do invoke_and_log_task 'feed:update' invoke_and_log_task 'summary:weekly_update' if [1,7,14,21].include? Time.now.day ENV['greeting'] = 'Hello again...' invoke_and_log_task 'spam_users' if Time.now.day == 5 end
Alternatively, you could just do
0 0 1,7,14,21 * * cd …
Just saying…
yeah thats right for this example.
In general it is much more convenient to have one dead-simple cronjob running (e.g. once every night) that goes through ruby where all the logic sits and can be tested, and then is executed (with loging and failure notification) then having oh-so-clever cronjobs that are hard to maintain/understand/update.
The alternative here would be to use the Whenever gem as well and have a schedule.rb built.
It also fits nicely in with capistrano. I’ve added it to my 2.3 temp;ate since I end up using cron tasks all the time.
I think this week’s RailsCast has a howto on it.
yep, this can be done with whenever/schedule, but imo the beauty of the approach is that its dead-simple, everything stays in ruby and error notifications/logs are created
Great tip!!! Thank you! I used the code today, it works beautifully.
PS – if you ever need a nice crontab web GUI, you can check out http://www.corntab.com
Cheers!
nice, ill use it if i do my next weird crontab command 🙂
Note that using the @weekly dealie in crontab is also an option.
As an application developer, I might consider doing this. As a sysadmin, I start tearing my hair out when dealing with other people’s partial crontab reimplementations. 😉