【问题标题】:Rails Caching, continue storing expired valueRails 缓存,继续存储过期值
【发布时间】:2012-11-12 15:44:09
【问题描述】:

我在我们的一个仪表板系统上有一个很长的数据库查询,我想缓存它,因为结果不需要实时准确,但可以从缓存中给出“足够接近”的值。

我希望用户无需等待即可完成此操作。我正在考虑使用类似的东西

Rails.cache.write('my_val', 'val', :expires_in => 60.minutes)

存储这个值,但我不相信它提供了我想要的确切功能。我想打电话给

 Rails.fetch('my_val') { create a background task to update my_val; return expired my_val}

似乎 my_val 在过期时已从缓存中删除。有什么方法可以访问这个过期的值,或者可能是另一个可以启用此功能的内置机制?

谢谢。

【问题讨论】:

  • 为什么不设置后台任务在过期前更新值呢?这样代码就不必等待了。
  • 好吧,如果后台任务已经在运行并且耗时过长,以至于缓存在完成之前就过期了,我想在它继续运行时返回旧值。
  • 这是不可行的。一旦缓存过期,该值为 null 并且您无法访问前一个缓存。增加过期时间......或者只是不为缓存条目设置过期时间。这样,该值将始终存在,并且一旦完成运行,您就可以使用后台任务覆盖该值

标签: ruby-on-rails ruby caching


【解决方案1】:

这样做:

Rails.cache.write('my_val', 'val')

永不过期

现在运行您的后台作业:

SomeLongJob.process

在 SomeLongJob.process 作业中执行以下操作:

def SomeLongJob.process
  some_long_calculation = Blah.calc
  Rails.cache.write('my_val', some_long_calculation)
end

现在用

读取数据
def get_value
  val = Rails.cache.read('my_val', 'val')
end

【讨论】:

  • delete 行是多余的吗?我假设write 将自动覆盖任何现有值,避免deletewrite 行之间的缓存命中问题。
  • 那行得通,我正试图再做一个调度工作,但每隔一小时左右启动一个 rake 任务并不是世界末日。如果缓存知道何时更新自己,我会更好,这是一个被调用的“on_experiation”块,但这可能是一些非常繁重的猴子补丁。
【解决方案2】:

Rails.cache.fetch:race_condition_ttl 选项与您正在寻找的内容非常接近:http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html#method-i-fetch

但据我所知,第一个请求仍然被阻止(只是后续请求在更新时获取旧值)。不知道为什么他们没有一路走下去。如果@drhenner 提到的模式被抽象成这样的选项会更好,但我还没有看到。

【讨论】:

    猜你喜欢
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-05-24
    • 1970-01-01
    • 2013-01-14
    • 2016-02-28
    • 2015-12-25
    • 1970-01-01
    相关资源
    最近更新 更多