Unable to run 2 dependent commands in the same whenever cron job - ruby-on-rails

I work on a Rails based website for which I have to create a sitemap using the sitemap_generator gem.
So far so good, until I reached the part where I have to automate the sitemap generation.
The 2 commands that I need to run in order to refresh the sitemap are direnv allow && rake sitemap:refresh.
I am trying to create a cron job by using the whenever gem and this is what I have inside config/schedule.rb:
# config/schedule.rb
set :output, "tmp/cron.log"
set :environment, "development"
every 1.minutes do
command "/Users/<user>/<project>/generate_sitemap.sh"
end
The generate_sitemap.sh file is in the project root and has the following content:
# generate_sitemap.sh
#!/bin/bash
direnv allow
rake sitemap:refresh
In order to activate the cron job, I execute whenever --update-crontab in the terminal. By running crontab -l, I have the following output:
# Begin Whenever generated tasks for: /Users/<user>/<project>/config/schedule.rb at: 2022-01-27 18:51:18 +0200
* * * * * /bin/bash -l -c '/Users/<user>/<project>/generate_sitemap.sh >> tmp/cron.log 2>&1'
# End Whenever generated tasks for: /Users/<user>/<project>/config/schedule.rb at: 2022-01-27 18:51:18 +0200
I have to mention that if I execute ./generate_sitemap.sh from the command line, it works. Furthermore, if I create a cron job as follows:
config/schedule.rb:
# config/schedule.rb
set :output, "tmp/cron.log"
set :environment, "development"
every 1.minutes do
rake "sitemap:refresh"
end
it is executed, but it results into an error since direnv allow was not executed beforehand.
My question is: how can I create a cron job which executes both direnv allow and rake sitemap:refresh?

Related

Ruby on Rails - Whenever Gem + Cron Not Running

TL;DR: My Whenever Gem scheduled task does not run at all automatically but will manually.
I posted about this earlier in the week but got no responses, I'm attempting to implement the Whenever gem into my RoR 5 application. Once a year I want it to run a method in my 'User' model, but for testing purposes I have made it once every minute, like so:
Schedule.rb:
set :output, "/home/ubuntu/workspace/log/cron.log"
set :environment, 'development'
every 1.minute do
runner "User.(methodhere)"
end
User.rb:
def self.(methodhere)
User.all.each do |user|
user.update(remaining_days: user.total_days)
end
end
In multiple places I have read that sometimes cronjobs dont run properly in development mode, so I jumped through all of the hoops to put my application into production mode, and that did not help.
I then found that you can manually run these jobs in the command line, which I then tried to do using the command found doing:
whenever --update-cron
then
crontab -l
which showed
# Begin Whenever generated tasks for:
* * * * * /bin/bash -l -c 'cd /home/ubuntu/workspace && bundle exec
bin/rails runner -e development '\''User.new.(methodhere)'\'' >>
/home/ubuntu/workspace/log/cron.log 2>&1'
Running this manually:
/bin/bash -l -c 'cd /home/ubuntu/workspace && bundle exec
bin/rails runner -e development '\''User.(methodhere)'\'' >>
/home/ubuntu/workspace/log/cron.log 2>&1'
makes it work, and executes the (methodhere). Whenever just does not make it run automatically at the set interval.
Another thing I found was to try and restart cron, through cron restart, but I am receiving:
cron: can't open or create /var/run/crond.pid: Permission denied
I'm not sure if that has anything to do with the IDE I'm using, Cloud 9.
Many google searches have left me with nothing.
NOTE: I'm a very new developer with RoR, so any guidance on the matter would be greatly appreciated, thanks!

How to put filename in cron job (rails)?

I am using whenever gem. I am calling runner to run job. I called runner for the same job by 3 type. I am not sure which one working here.
I used command whenever --update-crontab project_name
then crontab -l
Schedule.rb
set :output, 'log/whenever.log'
every 1.days , :at => '03:51 pm' do
runner "SomeJob.perform_later", filename: '/app/jobs/some_job.rb'
end
every 1.days , :at => '03:51 pm' do
runner "SomeJob.perform_later", filename: './app/jobs/some_job.rb'
end
every 1.days , :at => '03:51 pm' do
runner "SomeJob.perform_later"
end
Also these ran only once. I am having difficult time to debug here.
Can anyone tell which one is correct? Also what is the correct way to debug in this scenario?
Running crontab -l gives me this -
51,51,51 16 * * * /bin/bash -l -c 'cd /home/rahul/orthoweb && bin/rails runner -e production '\''InvestigationStopJob.perform_later'\'' >> log/whenever.log 2>&1
To run in development environment I ran this command -
whenever --update-crontab --set environment='development'
But this gives me this message -
## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated.
There are some issues with running the jobs in development mode.
What works is that you have to close all tabs before running your job and scheduler.
There is no need to change setup of your env in schedule file.
To run in development use this
whenever --update-crontab --set environment='development'
Without specifying filename jobs does not run properly. The following line works correctly.
every 1.days , :at => '03:51 pm' do
runner "SomeJob.perform_later", filename: '/app/jobs/some_job.rb'
end
I think, that the resulting crontab contains only one of those tasks, because they were overwritten.
To be sure, check out the resulting crontab by typing whenever. I think that there will be only one entrance.

Rails: Cron jobs with whenever gem

I'm new to cron job as well as rails. I have installed whenever gem. Now I want to delete a file from tmp/cache/foo.txt.
schedule.rb
every 5.minutes do
command "rm '#{path}/tmp/cache/foo.txt' "
end
And when i run whenever command it says:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /bin/bash -l -c 'rm '\''/home/techbirds/shivam/tmp/cache/foo.txt'\'''
## [message] Above is your schedule file converted to cron syntax; your crontab file was not updated.
## [message] Run `whenever --help' for more options
So how to do it from starting?
You should update crontab (configuration file that defines commands to run periodically on a desired schedule) according to you new schedule.rb rules, so you should run the following command (if this job is set to a specific environment in your schedule.rb you should also --set environment):
whenever --update-crontab
To view your current jobs use crontab -e (jobs generated by whenever would be enclosed in # Begin Whenever and # End Whenever blocks).

Cron Job not working using whenever gem

I am trying to learn Cron Job and whenever gem.
In my app i have created a rake task.
require 'rubygems'
namespace :cron_job do
desc "To Check Users Inactivity"
task user_inactivity: :environment do
p "Inactive Users..."
end
end
and in schedule.rb i have wrote like this
every 1.minute do
rake "cron_job:user_inactivity", environment: "development"
end
and in my terminal i wrote two commands
whenever --update-crontab
and then
sudo /etc/init.d/cron restart
but nothing is happening after 1 minute.
I checked my console for p messages and nothing happens. Do i miss something?
The output won't show in your console.
You have to set the output log path by:
set :output, "/path/to/my/cron_log.log"
Then check the log.

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.

Resources