Implement Delayed job and cron job in Heroku - ruby-on-rails

I had developed an application that has delayed job and cron job and I need to deploy it to Heroku. I realized my delayed job need Heroku adds-on, "Heroku Scheduler Standard" and it costs $34.50.
1) Does that mean I need to buy that so that my delayed and cron job will run automatically?I wonder if delayed job and cron job can be done by using Heroku schedular then why we still need javan/whenever and collectiveidea/delayed_job? Can I use these in Heroku preferably in free condition?
2) My cron job does not worked in Heroku. How do I run my whenever gem in heroku?

There appear to be a couple of thoughts intermixed in your question. I'll do my best to separate them:
a) DelayedJob on Heroku
One way to process jobs queued in DelayedJob (i.e. records sitting in the delayed_jobs table in your database) is to run the following rake task:
$ rake jobs:work
On heroku, this rake task is commonly run via a 'worker' process.
By default for rails apps, your heroku app should already come with a slider for 'workers' (initially set to 0) that will run the rake task above. Merely sliding this to '1' (which will cost you around $34.00 per month) will launch the DelayedJob dequeue process in the background on a dedicated heroku instance, with your codebase, independent of your web dynos.
Note that DelayedJob does NOT require Heroku's "Scheduler" add-on.
Also note that heroku charges by hours of processing per month. So, if you slide your 'worker' to '1' for one hour a month, and then slide it back to '0' again when you're done, you will be paying far, far less than the ~$34 charge. There is a way to slide workers on and off programatically too.
b) Cron on Heroku
As it stands, managing your own, customized cron file is not possible on heroku or other cloud-based app service providers. Everything is ephemeral, and deployed files cannot be altered by you or your code.
Heroku's Scheduler is the appropriate add-on in this case to replace cron. You should be able to set tasks in your heroku scheduler to do what your cron tasks are currently doing.
Last I checked, heroku's scheduler was free (see: https://addons.heroku.com/scheduler), so I'm not sure why you state it is $34.50.
Hope this helps.

Related

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

Heroku scheduler is not working but running rake manually working

I have a task that takes over 45 minutes. It runs successfully with
$ heroku run rake:sales
I also doublechecked my settings in scheduler based on this question. Everything looks fine.
In order to prevent run-away jobs, jobs that run longer than their frequency will be terminated. For example, a job that runs every 10 minutes will be terminated after running for 10 minutes.
What's happening is that your rake task is running for the first 10 minutes, but Heroku aborts it after that elapses. They suggest using a background job queue for long-running tasks.
Source:
https://devcenter.heroku.com/articles/scheduler#long-running-jobs
Apart from the long-running issue that #KKobayashi has alluded to, you may not have the correct rake file created for the scheduler to run:
Heroku Scheduler:
For Rails, the convention is to set up rake tasks. To create your
scheduled tasks in Rails, copy the code below into
lib/tasks/scheduler.rake and customize it to fit your needs
Have you tried putting your tasks into a a scheduler.rake file?
It could be that you're scheduling the task for an app other than the one you intend to schedule it for.
To check, open the scheduler (heroku addons:open scheduler) and check the url. If you see another app's name in the url, you need to add the scheduler addon again i.e.:
heroku addons:create scheduler:standard
Now open it again (heroku addons:open scheduler)

Ruby on Rails: need to log data on a daily basis (hosted on Heroku)

Cronjob vs Scheduler for Heroku.
Sounds like you just need a periodic task to run once per day. The currently recommended way to do that at Heroku is to use the scheduler add-on:
Scheduler is an add-on for running jobs on your app at scheduled time intervals, much like cron in a traditional server environment.
A dashboard allows you to configure jobs to run every 10 minutes, every hour, or every day, at a specified time. When invoked, these jobs will run as one-off processes and show up in your logs as a process named run.N.
The basic process is pretty simple:
Set up a Rake task to do whatever it is you need to do:
desc "This task does ..."
task :your_task => :environment do
# Do something interesting...
end
Add the scheduler add-on in the usual manner:
$ heroku addons:add scheduler:standard
Then add your new Rake task through the Heroku dashboard.
If you want to run your periodic task outside Heroku then set up a cron job to run the appropriate Rake task.
You probably want to put this task into a Cron job which handles recurring processes or tasks.
Here is an excellent screencast on the subject courtesy of Ryan Bates:
http://railscasts.com/episodes/164-cron-in-ruby-revised
If you need to set up recurring jobs on Heroku, you need only add your tasks to lib/tasks/scheduler.rake and configure them using the Schedular Add-on
http://devcenter.heroku.com/articles/scheduler

"Whenever" gem running cron jobs on Heroku

I created an app that uses the whenever gem. The gem creates cron jobs. I got it working locally but can't seem to get it working on heroku cedar. What's the command to do this?
running:
heroku run whenever --update-crontab job1
doesn't work
Short answer: use the scheduler add-on: http://addons.heroku.com/scheduler
Long answer: When you do heroku run, we
spin up a dyno
put your code on it
execute your command, wait for it to finish
throw the dyno away
Any changes you made to crontab would be immediately thrown away. Everything is ephemeral, you cannot edit files on heroku, just push new code.
You need to add Heroku Scheduler addon.
You can add it directly from your dashboard or using following commands:
install the add-on:
heroku addons:create scheduler:standard
Create a rake task in lib/tasks
# lib/tasks/scheduler.rake
task :send_reminders => :environment do
User.send_reminders
end
Schedule job
Visit Heroku Dashboard
Open your app
Select Scheduler from add-ons list
Click Add Job, enter a task and select frequency.
e.g. Add rake send_reminders, select "Daily" and "00:00" to send reminders every day at midnight.
The other answers specify you should use the Heroku Scheduler add-on, and it is able to run a background tasks indeed, but it doesn't support the flexibility of cron.
There's another add-on, called Cron To Go, that is able to run your jobs on one-off dynos with cron's flexibility. You can also specify a timezone for your job and get notifications (email or webhook) when job fail, succeed or start.
(Full disclosure - I work for the company that created and operates Cron To Go)
If you want to:
Use Heroku Scheduler
Run tasks every minute (not 10 min)
Don't care about dyno hours
This was my solution hack to run jobs every minute - assuming the task completes in under 60 seconds.
task start_my_service: :environment do
1.upto(9) do |iteration|
start_time = DateTime.now
Services::MyService.call
end_time = DateTime.now
wait_time = 60 - ((end_time - start_time) * 24 * 60 * 60).to_i
sleep wait_time if wait_time > 0
end
end
Heroku doesn't support cron jobs. And there are two drawbacks to the Heroku Scheduler :
you cannot choose an arbitrary interval or time at which to run jobs (it's either every 10 mins, 1 hour or daily).
your jobs are not defined in code, hence not in your versioning system and not easy to keep track of or modify.
Heroku does provide an alternative : custom clock processes. But the clock process requires its own dyno, and "Since dynos are restarted at least once a day some logic will need to exist on startup of the clock process to ensure that a job interval wasn’t skipped during the dyno restart".
Simple scheduler is a gem made specifically made for scheduling on Heroku, but seems a bit hackish.
I ended up using sidekiq-cron. Only drawback : if sidekiq is down right when a job is scheduled to run, the job won't run.

Why would my rake tasks running via cron get invoked twice?

I have a rails app with the whenever gem installed to setup cron jobs which invoke various rake tasks. For reasons unbeknownst to me, each rake task gets invoked twice at precisely the same time. So my db backup task backs up the db twice at 4:00am.
Inspecting crontab reveals correct syntax for all of the cron jobs, so I don't think this is an issue with the whenever gem not correctly configuring the cron jobs. Also confusing is that in both staging and production environments and can invoke tasks on the command line and they only run once.
Any thoughts on what would cause this? I'm at a complete loss troubleshooting wise.
The number of cron jobs that run depends on the number of application instances running in the server box. Are you have two instances of rails application running in the same server box?

Resources