Подтвердить что ты не робот

Очистить Memcached от Heroku Deploy

Каков наилучший способ автоматического удаления Memcached при развертывании моего приложения rails в Heroku?

Я кэширую домашнюю страницу, а когда я вношу изменения и повторно развертываю, страница хранится в кеше, и обновления не включаются.

Я хочу, чтобы это было полностью автоматизировано. Я не хочу очищать кеш в консоли heroku при каждом развертывании.

Спасибо!

4b9b3361

Ответ 1

Я развертываю свои приложения с помощью bash script, который автоматизирует перенаправление GitHub и Heroku, миграцию базы данных, активацию режима обслуживания приложений и очистку кеша.

В этом script команда очистки кэша:

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

Это работает с Celadon Cedar с пакетом Heroku Toolbelt. Я знаю, что это не решение на основе Rake, но оно достаточно эффективно.

Примечание. Обязательно установите для параметра environment/-e команду runner значение production, поскольку оно будет выполнено в development в противном случае.

Изменить. У меня возникли проблемы с этой командой на Heroku с нескольких дней (Rails 3.2.21). У меня не было времени проверить происхождение проблемы, но удаление -e production выполнило трюк, поэтому, если команда не удалась, запустите это вместо:

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

Ответ 2

[На стеле кедра Целадона]

- [Обновление 18 июня 2012 года - это больше не работает, увидит, могу ли я найти другое обходное решение]

Самый чистый способ, с помощью которого я столкнулся с этими крючками после развертывания, - это защелка на активы: прекомпилировать задачу, которая уже вызывается во время компиляции пула. С призывом к asset_sync Gem за идею:

Rake::Task["assets:precompile"].enhance do
  # How to invoke a task that exists elsewhere
  # Rake::Task["assets:environment"].invoke if Rake::Task.task_defined?("assets:environment")

  # Clear cache on deploy
  print "Clearing the rails memcached cache\n"
  Rails.cache.clear
end

Я просто помещаю это в файл lib/tasks/heroku_deploy.rake, и он хорошо подбирается.

Ответ 3

То, что я закончил, это создать новую задачу rake, которая была развернута в heroku, а затем очистила кеш. Я создал файл deploy.rake и это он:

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

Теперь вместо того, чтобы печатать git push heroku, я просто набираю rake deploy: production.

Ответ 4

25 января 2013: это работает для приложения Rails 3.2.11, работающего на Ruby 1.9.3 на кедре

В вашем Gemfile добавьте следующую строку, чтобы заставить ruby ​​1.9.3:

ruby '1.9.3'

Создайте файл с именем lib/tasks/clear_cache.rake с этим контентом:

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

Наконец, я также рекомендую запустить heroku labs:enable user-env-compile в вашем приложении, чтобы его среда была доступна вам как часть предварительной компиляции.

Ответ 5

Помимо всего, что вы можете сделать внутри своего приложения, которое запускается при запуске приложения, вы можете использовать hookk для развертывания heroku (http://devcenter.heroku.com/articles/deploy-hooks#http_post_hook), который ударил бы по URL-адресу в вашем приложении, которое очищает кеш

Ответ 6

Я добавил config/initializers/expire_cache.rb с помощью

ActionController::Base.expire_page '/'

Прекрасно работает!

Ответ 7

Поскольку герой героя устарел, обновленная версия Solomons очень изящным ответом заключается в том, чтобы сохранить следующий код в 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

затем вместо git push heroku master введите rake deploy:production в командной строке. Чтобы просто очистить кеш, вы можете запустить rake cache:clear

Ответ 8

Решение, которое мне нравится использовать, следующее:

Во-первых, я реализую действие deploy_hook, которое ищет параметр, который я устанавливаю по-разному для каждого приложения. Обычно я просто делаю это на "домашнем" или "открытом" контроллере, так как он не занимает много кода.

### routes.rb ###

post 'deploy_hook' => 'home#deploy'

### home_controller.rb ###

def deploy_hook
  Rails.cache.clear if params[:secret] == "a3ad3d3"
end

И я просто говорю heroku, чтобы настроить крюк развертывания для публикации этого действия при каждом развертывании!

heroku addons:add deployhooks:http \
   --url=http://example.com/deploy_hook?secret=a3ad3d3

Теперь, каждый раз, когда я развертываю, heroku будет отправлять HTTP-сообщение обратно на сайт, чтобы сообщить мне, что развертывание работало нормально.

Работает как прелесть для меня. Конечно, секретный токен не "высокая безопасность", и это не следует использовать, если есть хороший вектор атаки для удаления вашего сайта, если кеши были очищены. Но, честно говоря, если сайт критичен для атаки, то не принимайте его на Heroku! Однако, если вы хотите немного увеличить защиту, вы можете использовать конфигурационную конфигурацию Heroku и вообще не иметь "токена" в исходном коде.

Надеюсь, что люди найдут это полезным.

Ответ 9

У меня просто была эта проблема, но я хотел придерживаться развертывания git без дополнительного script в качестве обертки.

Итак, мой подход заключается в том, чтобы написать файл во время генерации slug с помощью uuid, который отмечает текущую предварительную компиляцию. Это подталкивается как крючок в 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

Другой - это инициализатор, который проверяет этот идентификатор на кешированную версию. Если они отличаются друг от друга, была еще одна предварительная компиляция, и кэш будет признан недействительным.

Так что неважно, насколько часто приложение вращается вверх или вниз или на сколько узлов будет распределено работник, потому что генерация slug просто происходит один раз.

# /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

Мне нужно было использовать случайный идентификатор, потому что я не знаю, как получить хэш git или любой другой полезный идентификатор. Возможно, ENV[REQUEST_ID], но это также случайный идентификатор.

Хорошая вещь о uuid заключается в том, что она теперь не зависит от героку.