如何为单个请求或代码块绕过Rails.cache



我有一个API端点,它聚合了代码中的一组数据,这些代码利用Rails.cache在这里和那里获取小块数据。然而,有时我想要100%的最新数据,就好像Rails.cache是空的一样。显然,我可以在聚合数据之前清除缓存,但这会影响不相关的数据和请求。

有没有一种方法可以让rails中的请求表现为rails.cache为空,类似于rails.cache被配置为:null_store?

ActiveRecord中的查询缓存有类似的功能-一个"uncached"函数,您可以将块传递给它,块将在不启用查询缓存的情况下运行。我需要类似的东西,但一般来说是Rails.cache。

由于似乎没有现成的解决方案,我通过添加以下代码作为config/initializers/rails_cache.rb 编写了自己的解决方案

module Rails
  class << self
    alias :default_rails_cache :cache
    def cache
      # Allow any thread to override Rails.cache with its own cache implementation.
      RequestStore.store[:rails_cache] || default_rails_cache
    end
  end
end

这允许任何线程指定自己的缓存存储,然后用于所有的获取、读取和写入。因此,它不会从默认的Rails.cache中读取,也不会将其值写入默认的Rail.coache.

如果线程是长时间运行的,并且从启用缓存中受益,那么可以很容易地将其设置为自己的MemoryStore实例:

RequestStore.store[:rails_cache] = ActiveSupport::Cache.lookup_store(:memory_store)

如果你想完全关闭这个线程的缓存,你可以:null_store而不是:memory_store。

如果您不使用requestrongtore gem,则可以将"RequestStore.store"替换为"Thread.current"以获得相同的效果——只需更加小心跨请求重用线程即可。

最新更新