A Free Cron for Heroku via Platform API and Openshift
Heroku has a free cron add-on, but you require a credit card, Openshift has a cron gear but unfortunatly other problems. Heroku launched recently the Platform API, so let's hack a cronjob!
It's important to detach the long tasks from HTTP requests. Data Backup, feed fetching,.. are good examples of task, inside an Heroku project you can do:
heroku run rake fetch_feeds
And "rake fetch_feeds" will be executed remotely in your instance, but how is possible to automate the same request?
Easy! From another web cron and the heroku api!
APP_KEY=`(echo -n ":" ; heroku auth:token) | base64` ; echo $APP_KEY ⬆ ◼ KmQwZjAyMz Your Secret key kxMzc5NzIzZjY4Cn==
Now you need an app on Openshift, you can use this minimal Sinatra app or the default one.
rhc create-app crontest -t ruby-1.9 && cd crontest
rhc cartridge-add cron
The cron scripts are managed by the files inside .openshift, lets add .openshift/cron/minutely/crony and make it executable.
#!/bin/env ruby
# This is Magic Cron
def every ( minutes, name='cronjob' )
lock = "#{ENV['OPENSHIFT_DATA_DIR'] || ''}.#{name}.lock"
if !File.exists?(lock) or (Time.now - File.ctime(lock) > minutes)
File.write(lock, "")
true
yield
else
false
end
end
class Fixnum; def mins; self * 60; end; end
### Your script here ###
every 1.mins do
puts 'ciao'
end
every 2.mins, 'anotherjob' do
puts 'another'
end
paste
git add . && git commit -m "+ cron" && git push
Connecting to Openshift via ssh we should see the lock files in $OPENSHIFT_DATA_DIR.
Finally we can add the Heroku Platform API part:
every 15.mins, 'fetch_feeds' do
`curl -n -X POST https://api.heroku.com/apps/MYHEROKUAPP/dynos -H "Accept: application/vnd.heroku+json; version=3" -H "Content-Type: application/json" -H "Authorization: KmQwZjAyMz Your Secret key kxMzc5NzIzZjY4Cn==" -d "{\"attach\":false,\"command\":\"rake fetch_feeds\"}"`
end