Rails: Scheduled task to warm up the cache?

前端 未结 4 798
暗喜
暗喜 2021-02-06 08:08

I am using the following to cache a slow loading page using memcached:

caches_action :complex_report, :expires_in => 1.day

The controller ac

相关标签:
4条回答
  • 2021-02-06 08:36

    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.

    0 讨论(0)
  • 2021-02-06 08:39

    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.

    0 讨论(0)
  • 2021-02-06 08:53

    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.

    0 讨论(0)
  • 2021-02-06 09:03

    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 &
    
    0 讨论(0)
提交回复
热议问题