Clear Memcached on Heroku Deploy

前端 未结 9 1724
旧巷少年郎
旧巷少年郎 2020-12-13 09:18

What is the best way to automatically clear Memcached when I deploy my rails app to Heroku?

I\'m caching the home page, and when I make changes and redeploy, the pag

相关标签:
9条回答
  • 2020-12-13 09:42

    I just had this problem as well but wanted to stick to the git deployment without an additional script as a wrapper.

    So my approach is to write a file during slug generation with an uuid that marks the current precompilation. This is impelmented as a hook in assets:precompile.

    # /lib/tasks/store_asset_cacheversion.rake
    # add uuidtools to Gemfile
    
    require "uuidtools"
    
    def storeCacheVersion
      cacheversion = UUIDTools::UUID.random_create
      File.open(".cacheversion", "w") { |file| file.write(cacheversion) }
    end
    
    Rake::Task["assets:precompile"].enhance do
      puts "Storing git hash in file for cache invalidation (assets:precompile)\n"
      storeCacheVersion
    end
    
    Rake::Task["assets:precompile:nondigest"].enhance do
      puts "Storing git hash in file for cache invalidation (assets:precompile:nondigest)\n"
      storeCacheVersion
    end
    

    The other is an initializer that checks this id against the cached version. If they differ, there has been another precompilation and the cache will be invalidated.

    So it dosen't matter how often the application spins up or down or on how many nodes the worker will be distributed, because the slug generation just happens once.

    # /config/initializers/00_asset_cache_check.rb
    
    currenthash = File.read ".cacheversion"
    cachehash   = Rails.cache.read "cacheversion"
    
    puts "Checking cache version: #{cachehash} against slug version: #{currenthash}\n"
    
    if currenthash != cachehash
      puts "flushing cache\n"
      Rails.cache.clear
      Rails.cache.write "cacheversion", currenthash
    else
      puts "cache ok\n"
    end
    

    I needed to use a random ID because there is as far as I know no way of getting the git hash or any other useful id. Perhaps the ENV[REQUEST_ID] but this is an random ID as well.

    The good thing about the uuid is, that it is now independent from heroku as well.

    0 讨论(0)
  • 2020-12-13 09:44

    I deploy my applications using a bash script that automates GitHub & Heroku push, database migration, application maintenance mode activation and cache clearing action.

    In this script, the command to clear the cache is :

    heroku run --app YOUR_APP_NAME rails runner -e production Rails.cache.clear
    

    This works with Celadon Cedar with the Heroku Toolbelt package. I know this is not a Rake-based solution however it's quite efficient.

    Note : be sure you set the environment / -e option of the runner command to production as it will be executed on the development one otherwise.

    Edit : I have experienced issues with this command on Heroku since a few days (Rails 3.2.21). I did not have time to check the origin the issue but removing the -e production did the trick, so if the command does not succeed, please run this one instead :

    heroku run --app YOUR_APP_NAME rails runner Rails.cache.clear
    
    0 讨论(0)
  • 2020-12-13 09:47

    25 Jan 2013: this is works for a Rails 3.2.11 app running on Ruby 1.9.3 on Cedar

    In your Gemfile add the following line to force ruby 1.9.3:

    ruby '1.9.3'
    

    Create a file named lib/tasks/clear_cache.rake with this content:

    if Rake::Task.task_defined?("assets:precompile:nondigest")
      Rake::Task["assets:precompile:nondigest"].enhance do
        Rails.cache.clear
      end
    else
      Rake::Task["assets:precompile"].enhance do
        # rails 3.1.1 will clear out Rails.application.config if the env vars
        # RAILS_GROUP and RAILS_ENV are not defined. We need to reload the
        # assets environment in this case.
        # Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")
        Rails.cache.clear
      end
    end
    

    Finally, I also recommend running heroku labs:enable user-env-compile on your app so that its environment is available to you as part of the precompilation.

    0 讨论(0)
  • 2020-12-13 09:47

    Aside from anything you can do inside your application that runs on 'application start' you could use the heroku deploy hooks (http://devcenter.heroku.com/articles/deploy-hooks#http_post_hook) that would hit a URL within your application that clears the cache

    0 讨论(0)
  • 2020-12-13 09:47

    Since the heroku gem is deprecated, an updated version of Solomons very elegant answer would be to save the following code in lib/tasks/heroku_deploy.rake:

    namespace :deploy do
        task :production do
            puts "deploying to production"
            system "git push heroku"
            puts "clearing cache"
            system "heroku run rake cache:clear"
            puts "done"
        end
    end
    
    namespace :cache do
      desc "Clears Rails cache"
      task :clear => :environment do
        Rails.cache.clear
      end
    end
    

    then instead of git push heroku master you type rake deploy:production in command line. To just clear the cache you can run rake cache:clear

    0 讨论(0)
  • 2020-12-13 09:56

    What I ended up doing was creating a new rake task that deployed to heroku and then cleared the cache. I created a deploy.rake file and this is it:

    namespace :deploy do
    
        task :production do
            puts "deploying to production"
            system "git push heroku"
            puts "clearing cache"
            system "heroku console Rails.cache.clear"
            puts "done"
        end
    
    end
    

    Now, instead of typing git push heroku, I just type rake deploy:production.

    0 讨论(0)
提交回复
热议问题