测试和生产环境中的 ETag 值错误

发布于 2024-08-18 12:14:14 字数 1718 浏览 14 评论 0原文

我正在使用新的 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::Basestale? 方法调用 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生产 则不会。

我已经用 webrickthin 对其进行了测试

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

卸妝后依然美 2024-08-25 12:14:14

解决方案是 Category.all 方法在类级别缓存结果,因此一旦获取它,所有内容都会被缓存以供其余请求使用。

它在开发环境中不存在,因为每次重新加载模型时,因为在该环境中config.cache_classesfalse

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 was false!

冷弦 2024-08-25 12:14:14

我不知道标题行/参数是否有最大值,但是对于很多类别,ETag 值会变得很长,正如您的示例所示。

您可以找到最新的修改日期并将其用于 ETag,而不是创建包含所有创建/修改日期的大字符串。

此外您引用的文章使用了fresh?而不是stale?,包括其他一些方法。你为什么不使用那些?

编辑:在查看更新的链接中的文章时 解决方案似乎是,只填写一个 @category (与他们相同)。因此找到最后修改的类别

@category = Category.find(:first, :order => 'date DESC')

并使用该值生成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 of stale? 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 category

@category = Category.find(:first, :order => 'date DESC')

and use this value to generate the MD5 for the ETag.
Get the complete list of @categories only if you are rendering the page.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文