плохое значение ETag в тестовой и производственной среде - PullRequest
1 голос
/ 17 января 2010

Я использую новое решение для кэширования Rails, как описано здесь .

Среда development работает нормально, но тест и production отправляет неверный заголовок ETag, игнорируя параметр функции stale?.

Вот соответствующая часть одного из моих контроллеров:

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

Метод stale? ActionController::Base вызывает метод fresh_when, который устанавливает etag объекта Response, который имеет следующий код:

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"

Так что я просто не понимаю, что происходит, потому что когда я выбираю URL http://localhost:3000/admin/categories/ в среде development , ETag меняется каждый раз, когда я сохраняю на Category, но тест или производство это не так.

Я протестировал его с Webrick и thin

Ответы [ 2 ]

2 голосов
/ 18 января 2010

решение состояло в том, что метод Category.all кэшировал результаты на уровне класса, поэтому после его выборки все кэшировалось для остальных запросов.

его не было в среде разработки , потому что каждый раз, когда модель перезагружалась, потому что в этой среде config.cache_classes было false!

0 голосов
/ 17 января 2010

Я не знаю, существует ли максимум в строках / параметрах заголовка, но при большом количестве категорий значение ETag становится очень длинным, как уже показывает ваш пример.

Вместо создания большой строки, содержащей все даты создания / изменения, вы можете найти самую последнюю дату модификации и использовать ее для ETag.

Кроме того в цитируемой вами статье используется fresh? вместо stale?, включая некоторые другие методы. Почему вы их не используете?

Редактировать: При просмотре статьи в вашей обновленной ссылке решение, по-видимому, заключается в заполнении только одной @category (такой же, как они). Поэтому найти последнюю модифицированную категорию

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

и используйте это значение для генерации MD5 для ETag.
Получите полный список @categories, только если вы отображаете страницу.

...