Rails 3 - Trigger a task in the background in frequent intervals - ruby-on-rails

I need to schedule a task that needs to run on a particular interval.
What are the gems / plugins available in rails 3 for achieving the same? If we have a list, how should we choose one among them?

Whenever is by far the most popular gem for using cron to do this.
https://github.com/javan/whenever

Not sure a gem is needed at all for this, cron was built for exactly this purpose, why not leverage it?
This seems to be a good solution:
Rails3, Running rake task from cron
The gist: convert the job into a rake task, which you can run with an environment variable.

Related

Send email at specific time with 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)

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).

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

Cron tasks in Ruby on Rails

I'm new to Ruby on Rails, and I wanted to perform some periodical tasks but I found out that I didn't know how to set up any cron task in RoR. Is there any basic tutorial how to set up cron in RoR? Currently I'm running RoR on Webbrick with Mysql DB on Windows platform.
There are few ways to solve your problem.
If you want to use Cron, the best way of using it with Rails is to use a gem whenever. To find out more about whenever, and a quick tutorial on how to use it, check this Railscast Episode 164. Cron best suits when you have actions that need to be run every constant time interval (eg. emptying your users' trashes)
You can also use DelayedJob which best suits when you have some actions that last long time and you don't want your user wait until their actions finish (eg. when you deliver a lot of emails) or when you want to take some actions in X hours. More about DelayedJob you will find here: https://github.com/collectiveidea/delayed_job
You can also Resque with Redis: https://github.com/blog/542-introducing-resque
Check out http://rubygems.org/gems/delayed_job
You can create a daemon script, which always be in memory.
For example, https://github.com/DAddYE/foreverb
For minimal setup of "cron-like" tasks in "core" rails/ruby, I created https://github.com/Ebbe/arask
No need to install anything (other than the gem) or setup anything outside of rails.
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 task: 'send:logs', cron: '0 2 * * *' # At 02:00 every day
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.

Resources