我有一个缓存的对象需要相当长的时间来计算(~30秒)。我每24小时重新计算一次这个对象,如果发生这种情况,有时用户如果恰好在同一时间就会遇到超时。我正在缓存的对象目前是这样的:
def matrix
Rails.cache.fetch(["matrix"], expires_in: 24.hours) do
# Math
end
end
我想做的是附加一个版本。这样我就可以用不同的方法在后台计算一个新的“矩阵”...
def rewrite_matrix
new_version = DateTime.now.to_s
Rails.cache.fetch(["matrix", new_version], expires_in: 24.hours) do
# Math
end
$matrix_version = new_version # This feels like a faux pas.
end
然后将我的矩阵方法更改为......
def matrix
$matrix_version ||= DateTime.now.to_s
Rails.cache.fetch(["matrix", $matrix_version], expires_in: 24.hours) do
# Math
end
end
我一直在阅读Ruby / Rails中的全局变量,并且一切都说他们不应该被触及?这个$ matrix_version变量是否可以在其他进程和其他用户中使用?无论如何,我希望有一个关于如何在后台解决或创建新缓存版本的想法,然后在它完成计算和存储时开始使用它。
答案 0 :(得分:1)
想到的第一个想法是先进行计算:
def matrix
Rails.cache.fetch('matrix') do
calculate_matrix
end
end
def rewrite_matrix
new_version = calculate_matrix
Rails.cache.delete('matrix')
Rails.cache.fetch('matrix') do
new_version
end
end
def calculate_matrix
#Math
end
如果你每24小时(在一个单独的过程中)调用rewrite_matrix
,它应首先执行工作,然后更新缓存,这将在用户工作时保持可用。
答案 1 :(得分:1)
如果需要24小时,我建议不要使缓存过期。相反,只需在准备好新版本时替换它。
class YourModel
def matrix
Rails.cache.fetch(["matrix"]) do
math
end
end
def self.recalculate_matrix
Rails.cache.set(["matrix"]) do
math
end
end
end
然后,也许使用whenever gem:
every 1.day, :at => '4:30 am' do
runner "MyModel.recalculate_matrix"
end