0

我有一个缓存对象,需要相当长的时间来计算(约 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 变量在其他进程和其他用户中是否可用?无论如何,我希望知道如何解决或在后台创建新的缓存版本,然后仅在完成计算和存储后才开始使用它。

4

2 回答 2

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

如果您rewrite_matrix每 24 小时调用一次(在一个单独的进程中),它应该首先完成工作,然后更新缓存,在它工作时它仍然可供用户使用。

于 2013-08-06T20:06:00.257 回答
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

然后,也许使用时 gem

every 1.day, :at => '4:30 am' do
  runner "MyModel.recalculate_matrix"
end
于 2013-08-06T20:06:35.197 回答