5

假设我有这样的方法:

  def foo
    Rails.cache.fetch("cache_key", :expires_in => 60.minutes) do
      return_something
    end
  end

return_something有时会返回一个nil值。发生这种情况时,我不希望将nil值缓存 60 分钟。相反,下次我调用时foo,我希望传递给的块fetch再次执行。

Rails.cache.fetch默认情况下是这样工作的吗?还是我必须实现这个功能?

更新(有答案)

事实证明,答案是否定的,至少在使用 Memcached 时是这样。

4

3 回答 3

2

这取决于您正在使用的缓存存储的实现。我会说它不应该缓存nil值,但是可以缓存空字符串。

看看dalli 商店的实现,即:

  def fetch(name, options=nil)
    options ||= {}
    name = expanded_key name

    if block_given?
      unless options[:force]
        entry = instrument(:read, name, options) do |payload|
          payload[:super_operation] = :fetch if payload
          read_entry(name, options)
        end
      end

      if !entry.nil?
        instrument(:fetch_hit, name, options) { |payload| }
        entry
      else
        result = instrument(:generate, name, options) do |payload|
          yield
        end
        write(name, result, options)
        result
      end
    else
      read(name, options)
    end
  end 
于 2012-10-15T10:01:55.817 回答
1

这个问题的更新答案是:默认情况下fetch缓存nil值,但使用dalli_store引擎可以通过cache_nils选项避免它:

Rails.cache.fetch("cache_key", expires_in: 60.minutes, cache_nils: false) do
  return_something
end
于 2016-12-12T17:23:43.317 回答
0

值得注意的是,Dalli 的默认值近年来发生了变化——nil-caching 的标志目前默认为 false。见 https://github.com/petergoldstein/dalli

绝对值得添加一个测试来检查您的设置是否符合您的预期(特别是对于生产模式)

于 2018-06-01T13:02:01.267 回答