mauvaise valeur ETag dans un environnement de test et de production
-
21-09-2019 - |
Question
J'utilise la nouvelle solution de mise en cache pour Rails comme décrit ici .
développement environnement fonctionne très bien, mais le test et production envoie en-tête ETag
invalide ignore le paramètre de la fonction stale?
.
Voici est la partie correspondante de l'un de mes contrôleurs:
def index
@categories = Category.all
if stale?(:etag => @categories)
respond_to do |format|
format.html
format.xml { render :xml => @categories }
format.json { render :json => @categories }
end
end
end
La méthode de stale?
du ActionController::Base
appelle la méthode fresh_when
qui définit la etag
de l'objet Response
, qui a le code suivant:
def etag=(etag)
if etag.blank?
headers.delete('ETag')
else
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end
end
Le modèle Category
envoie le cache_key
correct si je reçois dans tous les environnements:
>> Category.find(1).cache_key
=> "categories/1-20100117153353"
>> ActiveSupport::Cache.expand_cache_key(Category.find(:all))
=> "categories/1-20100117153353/categories/2-20100117152007/categories/3-20100116094423/categories/4-20100116094423/categories/5-20100116094423/categories/6-20100116094423/categories/7-20100116094423/categories/8-20100117145800/categories/9-20100117145808"
Je ne comprends pas ce qui se passe, parce que quand je sélectionne la http://localhost:3000/admin/categories/
URL avec développement environnement, le ETag
change à chaque fois que je sauve un Category
mais avec Test ou production il ne fonctionne pas.
Je l'ai testé avec webrick et mince
La solution
la solution est que la méthode de mise en mémoire cache Category.all
les résultats au niveau de la classe, donc une fois qu'il a été tout tiré par les cheveux a été mis en mémoire cache pour le reste des demandes.
il était pas là développement environnement parce que chaque fois que le modèle a été rechargé, car dans cet environnement le config.cache_classes
était false
!
Autres conseils
Je ne sais pas s'il y a un maximum de lignes sur tête / paramètres, mais avec beaucoup de catégories la valeur ETag devient très long, comme exemple montre déjà.
Au lieu de créer une grande chaîne contenant toutes les dates de création / modification, vous pouvez trouver la dernière date de modification et l'utiliser pour un ETag.
De plus l'article que vous avez cité utilise fresh?
au lieu de stale?
y compris d'autres méthodes. Pourquoi vous n'utilisez pas les?
Modifier Lorsque l'on regarde l'article dans votre lien mis à jour la solution semble être, pour remplir un seul @category
(comme ils le font). Par conséquent trouver la dernière catégorie modifiée
@category = Category.find(:first, :order => 'date DESC')
et utiliser cette valeur pour générer le MD5 pour le ETag.
Obtenez la liste complète des @categories
que si vous êtes rendu la page.