测试和生产环境中的 ETag 值错误
我正在使用新的 Rails 缓存解决方案,如此处所述。
开发环境工作正常,但测试和生产发送无效的ETag
标头会忽略的参数>过时?
功能。
这是我的一个控制器的相应部分:
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
ActionController::Base
的 stale?
方法调用 fresh_when
方法,该方法设置Response
对象的 etag
,其中包含以下代码:
def etag=(etag)
if etag.blank?
headers.delete('ETag')
else
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end
end
如果我得到,Category
模型会发送正确的 cache_key
它在每个环境中:
>> 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"
所以我根本不明白发生了什么,因为当我选择带有 developmenthttp://localhost:3000/admin/categories/ > 环境中,每次在 Category
上保存时,ETag
都会发生变化,但对于 test 或 生产 则不会。
我已经用 webrick 和 thin 对其进行了测试
I'm using the new caching solution for Rails as described here.
The development environment works fine, but the test and production sends invalid ETag
header ignores the parameter of the stale?
function.
Here is is the corresponding part of one of my controllers:
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
The stale?
method of the ActionController::Base
calls the fresh_when
method which sets the etag
of the Response
object, which has the following code:
def etag=(etag)
if etag.blank?
headers.delete('ETag')
else
headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}")
end
end
The Category
model sends the correct cache_key
if I get it in every environment:
>> 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"
So I simply don't understand what's going on, because when I select the URL http://localhost:3000/admin/categories/
with the development environment, the ETag
changes every time when I save on a Category
but with test or production it does not.
I've tested it with webrick and thin
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决方案是
Category.all
方法在类级别缓存结果,因此一旦获取它,所有内容都会被缓存以供其余请求使用。它在开发环境中不存在,因为每次重新加载模型时,因为在该环境中
config.cache_classes
为false
!the solution was that the
Category.all
method cached the results on class level, so once it was fetched everything was cached for the rest of the requests.it was not there in development environment because every time the model was reloaded because in that environment the
config.cache_classes
wasfalse
!我不知道标题行/参数是否有最大值,但是对于很多类别,ETag 值会变得很长,正如您的示例所示。
您可以找到最新的修改日期并将其用于 ETag,而不是创建包含所有创建/修改日期的大字符串。
此外您引用的文章使用了
fresh?
而不是stale?
,包括其他一些方法。你为什么不使用那些?编辑:在查看更新的链接中的文章时 解决方案似乎是,只填写一个
@category
(与他们相同)。因此找到最后修改的类别并使用该值生成MD5对于 ETag。
仅当您呈现页面时才获取
@categories
的完整列表。I do not know whether there is an maximum on header lines/parameters, but with a lot of categories the ETag value becomes very long, as your example already shows.
Instead of creating a big string containing all creation/modified dates, you could find the latest modification date and use that for an ETag.
Furthermore the article you quoted uses
fresh?
instead ofstale?
including some other methods. Why are you not using those?Edit: When looking at the article in your updated link the solution seems to be, to fill in just one
@category
(same as they do). Therefore find the last modified categoryand use this value to generate the MD5 for the ETag.
Get the complete list of
@categories
only if you are rendering the page.