Rails: Testing Cron Jobs in development environment - ruby-on-rails

I have a custom environment called 'reports' that is setup to hit a slave database. I am trying to configure some cron jobs using the Whenever gem and want to test them in development before I deploy. Is there any way to test cron jobs in development? Is there anyway I could schedule them locally and then start my reports server and see if they run? Thank You!

I would start off by reviewing how the gem itself (whenever gem) is conducting their tests. This is an extract from one of their functional test:
context "weekday at a (single) given time" do
setup do
#output = Whenever.cron \
<<-file
set :job_template, nil
every "weekday", :at => '5:02am' do
command "blahblah"
end
file
end
should "output the command using that time" do
assert_match '2 5 * * 1-5 blahblah', #output
end
end

Related

Rails Whenever gem and cron job not working on development environment

so this is like my first time doing a cron job, and also using a whenever gem.
this is what's in my schedule.rb
set :environment, :development
every 1.minute do
command "rails runner /home/ec2-user/projectA/scripts/download.rb"
end
It's running a script where it download's a file and does a few more other thing.
However, for some reason , the job is not running ? nothing is happening, the results are not returning. why is that?
UPDATE#############
i checked my cron log file, and it seems that it was running the script every minute as intended. however my results of the script is not producing as i would to run it manually.. why is that?

Run rails cron job with a life span

My Rails cron job:
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end
I only want this triggered when an attribute in MyModel is set to true and stop when it is set to false.
For triggered when an attribute (e.g. availability) in MyModel set to true and stop if it is set to be false, You need to create a method in MyModel like this -
def other_process
if attr
MyModel.some_process
rake "my:rake:task"
command "/usr/bin/my_great_command"
end
end
every 3.hours do
MyModel.other_process
end
The new Rails Active Job is designed for this very use case.
Active Job is a framework for declaring jobs and making them run on a variety of queuing backends. These jobs can be everything from regularly scheduled clean-ups, to billing charges, to mailings. Anything that can be chopped up into small units of work and run in parallel, really.
http://edgeguides.rubyonrails.org/active_job_basics.html

In Rails, how can I have a list of commands automatically run say every 24 hours?

I have a backend Rails JSON API.
Every X amount of hours, there is some data I would like to purge.
So I need to be able to run some commands every X hours.
How can I accomplish this in Rails?
Whenever is a Ruby gem that provides a clear syntax for writing and deploying cron jobs.
It is an easy way to write cron jobs to a cron tab file which is later on executed by the system. It provides you a nice DSL to schedule your tasks.
Let's assume you have a test action in YourModel that you want to run every 24 hours, so you will be doing this:
your_model.rb
def test
# Do Something...
end
schedule.rb
every 24.hours do
runner 'YourModel.test'
end
You need to run the following command on your project to do create the crontab:
whenever -i
You can use this gem whenever (https://github.com/javan/whenever), which will help you manage scheduling using crontab.

crontab didn't work in Rails rake task

I have a rake task in my Rails application,and when I execute the order in my rails app path /home/hxh/Share/ruby/sport/:
rake get_sportdata
This will work fine.
Now,I want to use crontab to make this rake to be a timed task .so,I add a task:
* * * * * cd /home/hxh/Share/ruby/sport && /usr/local/bin/rake get_sportdata >/dev/null 2>&1
But this doesn't work.I get the log in cron.log file:
Job `cron.daily' terminated
I want to know where the error is.
Does the "cd /home/hxh/Share/ruby/sport && /usr/local/bin/rake get_sportdata >/dev/null 2>&1" can work in your terminal?
But use crontab in Rails normally is not a good idea. It will load Rails environment every time and slow down your performance.
I think whenever or rufus-scheduler are all good. For example, use rufus-scheduler is very easy. In config\initializers\schedule_task.rb
require 'rubygems'
require 'rufus/scheduler'
scheduler = Rufus::Scheduler.start_new(:thread_name => "Check Resources Health")
scheduler.every '1d', :first_at => Time.now do |job|
puts "###########RM Schedule Job - Check Resources Health: #{job.job_id}##########"
begin
HealthChecker.perform
rescue Exception => e
puts e.message
puts e.backtrace
raise "Error in RM Scheduler - Check Resources Health " + e.message
end
end
And implement "perform" or some other class method in your controller, now the controller is "HealthChecker". Very easy and no extra effort. Hope it help.
So that you can test better, and get a handle on whether it works I suggest:
Write a shell script in [app root]/script which sets up the right environment variables to point to Ruby (if necessary) and has the call to rake. E.g., something like script/get-sportdata.sh.
Test the script as root. E.g., first do sudo -s.
Call this script from cron. E.g., * cd [...] && script/get-sportdata.sh. If necessary, test that line as root too.
That's been my recipe for success, running rake tasks from cron on Ubuntu. This is because the cron environment is a bit different than the usual shell setup. And so limiting your actual cron jobs to simple commands to run a particular script are a good way to divide the configuration into smaller parts which can be individually tested.

Run cron jobs on rails (deployed over several servers)

What is the best way to run cron jobs on rails, when different machines have different jobs to do?
For example, server 1 runs cron job A, while server 2 runs cron job B
Is there a way to deploy the cron files along when we do a regular cap deploy?
take a look at the whenever gem, http://github.com/javan/whenever
It is great for automating cron tasks with rails with a clear DSL. We have been using it production for several months now and it just works and is very lightweight. Some examples from their README:
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end
every 1.day, :at => '4:30 am' do
runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end
every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
runner "SomeModel.ladeeda"
end
every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
runner "Task.do_something_great"
end
The README is very thorough, but there is also a good screencast on railscasts: http://railscasts.com/episodes/164-cron-in-ruby
It easily integrates with capistrano with the following code (copied from README):
after "deploy:symlink", "deploy:update_crontab"
namespace :deploy do
desc "Update the crontab file"
task :update_crontab, :roles => :db do
run "cd #{release_path} && whenever --update-crontab #{application}"
end
end
As far as machine specific, you could use a local config file or even symlink the config/schedule.rb file on deploy. I think I would include a local file that would be symlinked on deploy local_schedule.rb and then put this at the top of the config/schedule.rb
if File.exists?(File.dirname(__FILE__) + '/config/local_schedule.rb')
require File.dirname(__FILE__) + '/local_schedule.rb'
end
Your schedule would run but then include anything local, just make sure it is symlinked before the cap task above is run and you should be good to go.
I hope this helps!

Resources