rails cache ruby-on-rails ruby caching cache-expiration

ruby-on-rails - rails 5.2 cache



Rails 4.0 expire_fragment/cache expiration no funciona (4)

Acabo de toparme con este tema y la forma en que me acerqué a tratarlo fue a través de expresiones regulares. Puede que no sea la solución más elegante, pero funciona bien.

ActionController::Base.new.expire_fragment(%r{offer_#{@offer.id}/*})

Sin embargo, agregar el skip_digest es mucho más agradable.

He intentado usar las capacidades de almacenamiento en caché de los rieles, pero no puedo caducar ningún fragmento de caché, aunque parecen caducar. Usando el ''Caché de Muñeca Rusa'' como se señala en el sitio tutorial Rails, estoy usando esta configuración

<% cache "all_available_releases" do %> <% @releases.each do |release| %> <% cache(release) do %> <html code with> <%ruby code @release.name blah blah blah%> <%end%> <%end%> <%end%>

Venzo el almacenamiento en caché externo en el controlador de release_controller.rb, donde utilizo expire_fragment ("all_available_releases") para caducar el fragmento. Lo uso en todos los métodos del controlador que actualiza o elimina o agrega una entrada.

Este es el registro de WEBrick, donde si bien el fragmento de expiración se registra, 5 líneas más tarde el fragmento caducado se lee y se utiliza mientras que no debería. Este ejemplo es después de una llamada de destrucción.

Processing by ReleasesController#destroy as HTML Parameters: {"authenticity_token"=>"***/***/********************+********=", "id"=>"2"} Release Load (0.1ms) SELECT "releases".* FROM "releases" WHERE "releases"."id" = ? LIMIT 1 [["id", "2"]] (0.1ms) begin transaction SQL (2.0ms) DELETE FROM "releases" WHERE "releases"."id" = ? [["id", 2]] (148.0ms) commit transaction Expire fragment views/all_available_releases (0.1ms) Redirected to http://127.0.0.1:3000/releases Completed 302 Found in 180ms (ActiveRecord: 150.2ms) Started GET "/releases" for 127.0.0.1 at 2013-07-03 13:09:51 +0300 Processing by ReleasesController#index as HTML Read fragment views/all_available_releases/41cb0a928326986f35f41c52bb3d8352 (0.1ms) Rendered releases/index.html.erb within layouts/application (0.6ms) Completed 200 OK in 5ms (Views: 4.0ms | ActiveRecord: 0.0ms)

Incluso intenté usar Rails.cache.delete("all_available_releases") y tampoco funcionó.

si <%cache "all_available_releases"%> (y uno <%end%> ) de mi html.erb, el almacenamiento en caché funciona bien y expira cada vez que debería.


Creo que el problema es que cuando almacena en caché el fragmento en su vista, se agrega un resumen de caché a la clave de caché (views / all_available_releases / 41cb0a928326986f35f41c52bb3d8352 ), pero expire_fragment no usa el resumen (views / all_available_releases).

Si agrega skip_digest: true a la llamada de caché en la vista, debe evitar que se use el resumen.

<% cache "all_available_releases", skip_digest: true do %> <% @releases.each do |release| %> <% cache(release) do %> <html code with> <%ruby code @release.name blah blah blah%> <%end%> <%end%> <%end%>

Los resúmenes de caché solo están destinados a ser utilizados con caducidad automática de caché. Si necesita caducar manualmente las claves de caché, entonces no puede usar los resúmenes de caché.


En Rails 5 di los siguientes pasos para reventar el caché sin recurrir a skip_digest: true . Nuestro problema era que cambiar el valor de las cadenas I18n no se refleja en el resumen de caché calculado, por lo que la caché no se eliminaría automáticamente.

Aquí está la vista donde se define el bloque de caché:

/ views/layouts/_footer.html.slim - cache :footer do span= t(''shared.footer'')

Luego en la consola Rails corro:

fragment = ActionController::Base.new.view_context.cache_fragment_name(:footer, virtual_path: ''layouts/_footer.html.slim'') ActionController::Base.new.expire_fragment(fragment)

cache_fragment_name resolverá el resumen basado en el argumento de la palabra clave virtual_path .


Jbuilder no es compatible con skip_digest. Después de muchos enfoques fallidos, decidí compartir mis respuestas aquí, ya que está muy relacionado, aunque no con una vista de rieles, como es el problema anterior.

Aquí hay un Q / issue relacionado en el que DHH básicamente le dice al chico que no puede caducar fragment_caches explícitamente. https://github.com/rails/cache_digests/issues/35 Todo no es cuadrado, así que aquí hay una forma de evitar esto:

class MenuController def index json = Rails.cache.fetch(''clients'') do @items = Menu.all render_to_string( template: ''menu/index'', locals: {items: @items}) end render json: json end end

entonces puedes caducar explicitamente esto en cualquier lugar, como en un observador

class MenuCacheObserver < ActiveRecord::Observer observe :menu, :menuitem, :menusubnavigation def after_save obj Rails.cache.delete(:clients) end end

En algunos casos esto puede tener sentido. En general, en la mayoría de los casos, debería usar el objeto en la entrada de la memoria caché, ¡como json.cache! @my_object do json.cache! @my_object do envolver la vista jbuilder. De esta forma, se invalidará cuando se actualice updated_at en el objeto.