ruby on rails - Borrar Memcached en Heroku Implementar
ruby-on-rails ruby-on-rails-3 (9)
Acabo de tener este problema también, pero quería seguir con la implementación de git sin un script adicional como envoltorio.
Así que mi enfoque es escribir un archivo durante la generación de slug con un uuid que marca la precompilación actual. Esto se impulsa como un gancho en los 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
El otro es un inicializador que verifica esta identificación con la versión en caché. Si difieren, ha habido otra precompilación y la memoria caché se invalidará.
Por lo tanto, no importa con qué frecuencia la aplicación gira hacia arriba o hacia abajo o en cuántos nodos se distribuirá el trabajador, porque la generación de slug solo ocurre una vez.
# /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
Necesitaba usar una identificación aleatoria porque, hasta donde yo sé, no hay manera de obtener el hash git o cualquier otra identificación útil. Tal vez el ENV[REQUEST_ID]
pero esta es una identificación aleatoria también.
Lo bueno de la uuid es que ahora también es independiente de heroku.
¿Cuál es la mejor manera de borrar automáticamente Memcached cuando despliego mi aplicación Rails a Heroku?
Estoy almacenando en caché la página de inicio, y cuando realizo cambios y vuelvo a desplegar, la página se sirve desde el caché y las actualizaciones no se incorporan.
Quiero que esto sea totalmente automatizado. No quiero tener que borrar el caché en la consola heroku cada vez que despliegue.
¡Gracias!
Aparte de todo lo que pueda hacer dentro de su aplicación que se ejecute en ''inicio de la aplicación'', podría usar los ganchos de implementación heroku (http://devcenter.heroku.com/articles/deploy-hooks#http_post_hook) que afectarían una URL dentro de su aplicación. eso borra la caché
Dado que la joya heroku está en desuso, una versión actualizada de la respuesta muy elegante de Solomons sería guardar el siguiente código en 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
luego, en lugar de git push heroku master
rake deploy:production
en línea de comandos. Para borrar el caché, puede ejecutar el rake cache:clear
Despliego mis aplicaciones usando un script bash que automatiza el empuje de GitHub & Heroku, la migración de la base de datos, la activación del modo de mantenimiento de la aplicación y la acción de borrado del caché.
En este script, el comando para borrar el caché es:
heroku run --app YOUR_APP_NAME rails runner -e production Rails.cache.clear
Esto funciona con Celadon Cedar con el paquete Heroku Toolbelt. Sé que esto no es una solución basada en Rake, pero es bastante eficiente.
Nota: asegúrese de establecer el environment
/ -e
opción del comando del runner
en production
ya que de lo contrario se ejecutará en el development
.
Editar : He tenido problemas con este comando en Heroku desde hace unos días (Rails 3.2.21). No tuve tiempo de verificar el origen del problema, pero eliminar la -e production
hizo el truco, por lo que si el comando no funciona, ejecuta este en su lugar:
heroku run --app YOUR_APP_NAME rails runner Rails.cache.clear
He agregado config/initializers/expire_cache.rb
con
ActionController::Base.expire_page ''/''
¡Funciona dulce!
La solución que me gusta usar es la siguiente:
Primero, implemento una acción deploy_hook que busca un parámetro que configuro de manera diferente para cada aplicación. Por lo general, solo hago esto en el controlador "doméstico" o "público", ya que no requiere tanto código.
### routes.rb ###
post ''deploy_hook'' => ''home#deploy''
### home_controller.rb ###
def deploy_hook
Rails.cache.clear if params[:secret] == "a3ad3d3"
end
¡Y simplemente le digo a heroku que configure un gancho desplegable para publicar en esa acción cada vez que despliegue!
heroku addons:add deployhooks:http /
--url=http://example.com/deploy_hook?secret=a3ad3d3
Ahora, cada vez que despliegue, heroku hará una publicación HTTP en el sitio para informarme que el despliegue funcionó bien.
Funciona como un encanto para mí. Por supuesto, el token secreto no es de "alta seguridad" y esto no debería usarse si hubiera un buen vector de ataque para derribar su sitio si se eliminaban los cachés. Pero, sinceramente, si el sitio es tan crítico para atacar, ¡entonces no lo alojes en Heroku! Sin embargo, si desea aumentar un poco la seguridad, podría usar una variable de configuración de Heroku y no tener el ''token'' en el código fuente.
Espero que la gente lo encuentre útil.
Lo que terminé haciendo fue crear una nueva tarea de rake que desplegó en heroku y luego borró el caché. Creé un archivo deploy.rake y este es:
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
Ahora, en lugar de escribir git push heroku, simplemente escribo rake deploy: producción.
[En la pila Celadon Cedar]
- [Actualización del 18 de junio de 2012 - esto ya no funciona, verá si puedo encontrar otra solución alternativa]
La manera más limpia que he encontrado para manejar estos enganches posteriores al despliegue es engancharme a los activos: tarea de precompilación que ya se llama durante la compilación de slug. Con un guiño a asset_sync Gema para la idea:
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
Acabo de poner esto en un archivo lib / tasks / heroku_deploy.rake y se recoge muy bien.
25 de enero de 2013: esto funciona para una aplicación Rails 3.2.11 que se ejecuta en Ruby 1.9.3 en cedro
En su Gemfile
agregue la siguiente línea para forzar a ruby 1.9.3:
ruby ''1.9.3''
Crea un archivo llamado lib/tasks/clear_cache.rake
con este contenido:
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
Finalmente, también recomiendo ejecutar heroku labs:enable user-env-compile
en su aplicación para que su entorno esté disponible para usted como parte de la precompilación.