Send email at specific time with rails - ruby-on-rails

I want to automatically send a list of orders to all my suppliers from monday to friday at 11:00am. How can I do that ?
I am using Rails 5.1
I know that ActiveJobs has the Notifier.deliver_later function but if I'm right, it only works with relative times (eg: 10 hours from now). I actually need emails to be sent at 11:00 precise.

You can use whenever gem for this task. It provides a clear syntax for writing and deploying cron jobs.
Install this gem or add in gemfile. Go to your project directory and run whenevrize ..
$ cd /apps/my-great-project
$ wheneverize .
It creates a config/schedule.rb file in your project. Now you can add your task in this file and the gem will take care of everything.
For your case it'll look something like this.
every :weekday, at: '11:00 am' do
runner "MyModel.task_to_run_at_eleven_in_the_morning_on_weekdays"
end

I'd suggest you use Sidekiq with Sidekiq-cron this gem can work on high loaded projects, has Sidekiq UI (from Sidekiq), you can observe and relaunch jobs by your self from Sidekiq UI side.
Sidekiq more flexible and more useful can works with concurrency, has queues with privileges etc. (all advantages of Sidekiq)

Related

Rails 5 Regular Tasks Without Cron

I'm new to Rails so I'm not sure if this is a stupid question but...
I have to run regular tasks to populate data to my Rails app. Today I use the whenever gem to create Cron entries to run these tasks on my system. I want to migrate my Rails app to Docker so that I can scale it more easily. I know that in Drupal(PHP) there is Poorman's Cron which uses requests to drive schedules.
Is there a way to implement scheduling inside Rails without using Cron or a better way of managing regular tasks that works well with Rails?
Yes, I created https://github.com/Ebbe/arask to keep stuff simple.
No need to install anything (other than the gem) or setup anything outside of rails. No background process, except for the actual job.
Add gem 'arask' to your Gemfile, run bundle install, rails generate arask:install and rails db:migrate.
Now you can setup your tasks in the file config/initializers/arask.rb:
arask.create script: 'puts "IM ALIVE!"', interval: :daily
arask.create task: 'my:awesome_task', interval: :hourly
arask.create task: 'my:other_awesome_task', interval: 2.hours
The tasks will automatically run if the server is running.
Is there a way to implement scheduling inside Rails without using Cron
or a better way of managing regular tasks that works well with Rails?
Cron is pretty much the go to tool for running scheduled activities on *nix system and most gems actually leverage cron under the hood, in fact avoiding cron is probably a lot more work unless you want to use a third party service.
One of the new features of Rails 5 is ActiveJob:
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.
It can be used with several backends:
Sidekiq
Resque
Sucker Punch
Queue Classic

Setting up a rake task with Resque Scheduler - Rails 4

I am on Rails 4 using the Resque Scheduler gem.
I am also using the sitemap generator gem in order to dynamically generate my sitemap.
I am having trouble figuring out the best way to schedule a rake task with resque scheduler. The sitemap generator recommends whenever, but I am assuming resque scheduler can accomplish the same thing (don't want to install another gem if I don't have to).
Does anyone know how to set this up?
I would like to run rake sitemap:refresh:no_ping every 5 hours.
I was thinking I would just schedule a background job and run it from there:
# resque_schedule.yml
update_sitemap:
every: 5h
class: "SitemapUpdater"
description: "This job refreshes the sitemap"
# sitemap_updater.rb
class SitemapUpdater
#queue = :sitemap_queue
def self.perform
# run rake task here
end
end
... however, I'm not sure if this is a good practice. Any advice would be much appreciated.
I don't see a problem with your approach, you just must be aware that the scheduler is reset during every deployment, so if you do frequent deploys, your scheduled jobs might be run later or even not run at all, as documented:
IMPORTANT: Rufus every syntax will calculate jobs scheduling time starting from the moment of deploy, resulting in resetting schedule time on every deploy, so it's probably a good idea to use it only for frequent jobs (like every 10-30 minutes), otherwise - when you use something like every 20h and deploy once-twice per day - it will schedule the job for 20 hours from deploy, resulting in a job to never be run.
You might also run the rake from system cron itself, which is an even more lightweight solution as it requires no scheduler gems at all, just the rake task, and will be scheduled reliably in time.
See e.g. this answer for setting up the "every 5 hours" frequency in crontab and you might also need to study RVM wrappers if you use RVM for your ruby project (you must call rake using the RVM wrappers in such case, e.g. call /home/deploy/.rvm/wrappers/ruby-2.3.0#mygemset/rake instead of just rake).

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.

Need working examples of whenever gem in action

I recently made a Ruby gem called dvi_scrape for a new Rails web site that I'm working on. The dvi_scrape gem downloads web pages, scrapes financial data from them, process the data, and outputs the results to a Postgres database.
I'm able to get the Ruby command Dvi_scrape.dopeler to work as expected when executed manually. However, I'm unable to get it to work as expected when executed through cron.
How do I get this to work from cron on my WebFaction account?
The source code of the Rails site I'm working on this . The source code of the dvi_scrape gem is at this place .
I understand that config/schedule.rb is where you specify what scripts need to be run and at what time intervals. config/environment.rb is where you specify the environment. config/deploy.rb is where you specify what happens when you enter "cap deploy".
Are there any good examples of scripts that execute commands from certain gems at regular intervals? Please point me to some good examples on GitHub.
I don't have any "good examples on GitHub", but...
Assuming you have the gem installed into some specific web application (ie, you followed WebFaction's documentation for installing gems), you probably need to set some environment variables to make it usable when running from cron.
Try setting them in your cron job, like this (my example uses a 10-minute cron interval, change it to whatever you need):
*/10 * * * * GEM_HOME=$HOME/webapps/yourapp/gems RUBYLIB=$HOME/webapps/yourapp/lib PATH=$HOME/webapps/yourapp/bin your_command_here
Hope that helps!

A pulse or cron job for Rails app running in Heroku

I need some code executed once per day. Can be more than once a day and missing a day isn't the end of the world. That code will make sure users get some bonus points based on certain criteria. I'll keep track if they've already received the bonus points so it doesn't double up..
Some simple cron job calling a particular controller once in a while is perfect:
curl http://localhost/tasks/pulse
Of course a real crontab entry works great. Or is there an internal mechanism for this kind of thing in Rails? I'm using the latest stable Rails (currently 3.2.9).
The only wrinkle is this needs to work in Heroku too.
I just noticed Heroku's Scheduler. Looks great for Heroku. I can just run those tasks in my dev/test environment manually. Is this the best way to handle pulses/cron jobs in Rails? With rake tasks? Easy to incorporate running rake tasks in tests?
The Heroku Scheduler works great and is easy to set up!
You could check out this gem called whenever its a Ruby gem that provides a clear syntax for writing and deploying cron jobs. It's well maintained, not used it on Heroku myself but worth a look.
You can do loads of stuff like
every 3.hours do
runner "MyModel.some_process"
rake "my:rake:task"
command "/usr/bin/my_great_command"
end

Resources