Schedule a task in days or months - ruby-on-rails

I want to schedule a job in a far future. I seen tools like delayed_job can do some tasks asynchronously but it seems to be used for tasks scheduled in 5 minutes. Another solution can be to do a cron but it's not very efficient.
Is there a better way? I want to be sure than, if I reboot the server, tasks scheduled are not deleted.

You can use the rufus-scheduler. The example taken from the documentation shows how to do it:
require 'rufus-scheduler'
scheduler = Rufus::Scheduler.new
scheduler.at '2030/12/12 23:30:00' do
# do something at a given point in time
end
It also allows you to schedule in diferent ways:
scheduler.in '10d' do
# do something in 10 days
end
scheduler.every '3h' do
# do something every 3 hours
end
scheduler.cron '5 0 * * *' do
# do something every day, five minutes after midnight
# (see "man 5 crontab" in your terminal)
end

take a look at whenever gem
Seems like using
every '0 0 23 12 *' do
...
end
would work for this. It can take cron syntax so minute hour day month day-of-week. So this will run every December 23rd at 12:00am regardless of what day of the week that is.

Related

How to schedule a job at the end of each month in rails

I am using whenever gem to schedule jobs but I am not able to figure out how to schedule a job for the end of each month. Below is the which I want to run at the end of each month.
schedule.rb
every 1.month, at: 'end of the month at 5am' do
rake 'update_user', environment: ENV['RAILS_ENV']
end
Please help me fix this
Last day of the month is tricky in a cron job but you could use raw cron syntax to specify start of each month to run a job as follows:
#runs on at 12:00AM on the first of each month
every '0 0 1 * *' do
command "echo 'you can use raw cron syntax too'"
end
The syntax is minute, hour, day of month, month, day of week.
If running the job at the start of the month isn't an option, you could schedule the job run daily on the 28th-31st day each month and add logic in your take to only execute the job on the last day of each month as described in this answer

rufus schedular to run a job at every day at some particular time from the database

I am working with the rufus schedular to send sms every day, but I want to send the sms every day at 5 pm, I checked in the whenever gem and I can do something like:
every find_day.to_sym, :at => time do
rake "followup_mail:send_mass_email[#{massemail.id}]"
end
Time can be like "4:20am".
Any suggestions on how to set this up with rufus scheduler.
You can try this:-
recurrence_time = "17:00" #you can make it dynamic.
scheduled_time = Midnight.parse("every day at #{recurrence_time}")
scheduler.cron "#{scheduled_time}" do
# do something every day, recurrence_time
end
Here you can pass your recurrence from your database.
Hope it helps.
Try following solution:
scheduler.cron '0 17 * * *' do
# do something every day, 5pm
end

How to send notifications according to time zone in rails?

I am trying to send push notifications from my rails applications which are scheduled for every 7th day at 10am as cronjob using whenever gem.
Problem is that i have users from different time zones. from US,EU,AUS,IND etc. If I trigger from UTC time 10 am then users might get notifications at midnight, that's a very awful thing to do to disturb someone's sleep.
What can I do to schedule for every TimezoneUser to receive the notification at 10am of their timezone.
I am saving timezone for every user.
user_id time_zone
153 +10:00
155 +05:30
I would schedule the job to run every hour the desired day of the week, check which users have the time 10am now and send to them. This way you run the job 24 times in one day of the week covering the whole world timezones.
every '0 * * * 1' do
# Send notification to users that are at 10am now
end
In the above example, 0 * * * 1 is corresponding. (at minute 0) (every hour) (every day) (every month) (first day of week -Monday-)
If you want to send the notification on Sunday for example the number should be 7, Tuesday is 2 and so on.
In this case, you may write a rake task, so you still have an access to Rails application writing Ruby and might run the task through cron job any time needed.
Your rake task at lib/tasks/send_emails.rake assuming your using PostgreSQL could be:
namespace :users do
desc "use like rake users:send_emails"
task send_emails: :environment do
ActiveRecord::Base.transaction do
users = User.where("current_timestamp::TIMESTAMPTZ AT TIME ZONE INTERVAL time_zone::INTERVAL > ?", Time.zone.parse("2016/07/06 00:00"))
UsersMailer.send_newsletters(users).deliver_now
end
end
end
And then you set your cronjob to run a task rake like:
0 * * * * /bin/bash -l -c 'cd /home/your_user_name/path_to_rails_application/current/ && ~/.rvm/bin/rvm default do bundle exec rake users:send_emails RAILS_ENV=production --silent'

In Whenever gem, if we use every :month, does it mean the end of month or beginning?

When using the whenever gem we can set a monthly job like this :
every :month do
...
end
Will this run the job at the end of the month or at the start of the month? I want to run it at the end.
From the tests in whenever repo:
assert_equal '0 0 1 * *', parse_time(:month)
So :month will generate a cron entry that looks like 0 0 1 * *..
This corresponds to run once a month at midnight of the first day of the month.
One way to make the job run last day of the month would be to use the raw cron entry in wherever as follows:
every '0 0 L * *' do
...
end
This assumes that the cron on the server supports the L flag for representing the last day of the month.
See Cron job to run on the last day of the month for more about running a cron job on the last day of the month.

using whenever gem for scheduling a job every hour on Sunday

We are using whenever gem on our rails project and there is one task that need to be run every hour but only on the day of the sunday.
I understand that i can schedule tasks on hourly basis , by something like this:
every 1.hour do
# do something
end
and i also understand that i can schedule it for a particular time on sunday:
every :sunday, :at => "11:00pm" do
#do something
end
what i am looking for is some syntax to schedule this task for every hour on sunday.
You could do something like that
every '0 * * * 7' do
#...
end
The '0 * * * 7' part is cron syntax:
0 - minutes
first asterisk - every hour
second asterisk - every day
third asterisk - every month
7 - on sundays (7th day of the week)
EDIT - For more detailed information regarding cron tasks syntax, a very clear article can be found here: http://www.thesitewizard.com/general/set-cron-job.shtml

Resources