I am using the following to cache a slow loading page using memcached:
caches_action :complex_report, :expires_in => 1.day
The controller ac
Probably the most basic solution would be to set up a simple cron
entry to load up the page you'll want to have a 'hot' cache. This can be as easy adding the following to the crontab
of a user on your server using crontab -e
to open an editor:
*/15 * * * * wget -q http://yourwebpages.url/ > /dev/null 2>&1
What this will do is use wget
to fetch the data at the provided url every 15 minutes of every hour, day, month and year, ignore the results and not send *nix mail in case something goes wrong.
Here is an expansion on the previous cron based solution which uses curl's ability to store cookies so that you can auth in one step and then use the cookie again as an authenticated user in the next step. So if you put these lines in a script called "prepare_cache.sh"
rm /tmp/cookiejar
curl --request POST -d "login=<username>" -d "password=<password>" -c /tmp/cookiejar http://yourwebpages.url/login
curl --request GET -b -c /tmp/cookiejar http://yourwebpages.url/page_to_cache
rm /tmp/cookiejar
replacing the login and password parameters with ones which match the variables used in your login form and obviously the urls to call. I'm removing the cookiejar before to make sure there isn't a file there already and removing it at the end to make sure there isn't a cookie floating about with access levels it shouldn't have.
Then you can call this script with the cron job:
*/15 * * * * /home/myname/prepare_cache.sh > /dev/null 2>&1
And hopefully that should work. Seemed to work for me when I tried it.
If it's the process of running the report and collecting results that is time-consuming, you could cache those results (in place of, or along-side action caching) using Rails.cache.write
and Rails.cache.read
.
Then, because you needn't worry about authentication or making requests to the server, the act of running the query and caching the results from a cron job would be considerably simpler.
Take a look at this gem:
https://github.com/tommyh/preheat
The gem is for preheating your Rails.cache.
From the documentation:
This will "preheat" all your Rails.cache.fetch calls on your homepage. It is as simple as that!
#app/models/product.rb
def slow_method
Rails.cache.fetch("product-slow-method-#{self.id}") do
sleep 15
Time.now
end
end
#lib/tasks/preheat.rake
namespace :preheat do
desc "Preheat product caches"
task (:products => :environment) do
Preheat.it do
Product.all.each do |product|
app.get(app.products_path(product)) #or you could just call product.slow_method directly, whatever makes more sense
end
end
end
end
#crontab -e
0 * * * * /path/to/rake preheat:products RAILS_ENV=production 2>&1 >> #{Rails.root}/log/preheat.log &