two*_*ool 14 ruby caching ruby-on-rails calculated-columns
我有一个活动记录对象树,如:
class Part < ActiveRecord::Base
has_many :sub_parts, :class_name => "Part"
def complicated_calculation
if sub_parts.size > 0
return self.sub_parts.inject(0){ |sum, current| sum + current.complicated_calculation }
else
sleep(1)
return rand(10000)
end
end
end
Run Code Online (Sandbox Code Playgroud)
每次重新计算复杂的计算成本太高.所以,我需要一种缓存值的方法.但是,如果更改了任何部分,则需要使其缓存及其父级和祖父级等的缓存无效.
作为一个粗略的草稿,我创建了一个列来保存"部件"表中的缓存计算,但这闻起来有点腐烂.看起来应该有一种更简洁的方法来缓存计算值,而不会将它们填充到"真实"列旁边.
Aug*_*aas 28
我建议使用关联回调.
class Part < ActiveRecord::Base
has_many :sub_parts,
:class_name => "Part",
:after_add => :count_sub_parts,
:after_remove => :count_sub_parts
private
def count_sub_parts
update_attribute(:sub_part_count, calculate_sub_part_count)
end
def calculate_sub_part_count
# perform the actual calculation here
end
end
Run Code Online (Sandbox Code Playgroud)
好又容易=)
您可以在Rails缓存中填充实际缓存的值(如果需要将其分发,请使用memcached).
困难的一点是缓存到期,但缓存到期是不常见的,对吧?在这种情况下,我们可以依次遍历每个父对象并删除其缓存.我在你的类中添加了一些ActiveRecord魔法,以使父对象本身变得简单 - 你甚至不需要触摸你的数据库.记得Part.sweep_complicated_cache(some_part)在你的代码中适当地调用- 你可以将它放在回调等中,但是我不能为你添加它,因为我不知道什么时候complicated_calculation会改变.
class Part < ActiveRecord::Base
has_many :sub_parts, :class_name => "Part"
belongs_to :parent_part, :class_name => "Part", :foreign_key => :part_id
@@MAX_PART_NESTING = 25 #pick any sanity-saving value
def complicated_calculation (...)
if cache.contains? [id, :complicated_calculation]
cache[ [id, :complicated_calculation] ]
else
cache[ [id, :complicated_calculation] ] = complicated_calculation_helper (...)
end
end
def complicated_calculation_helper
#your implementation goes here
end
def Part.sweep_complicated_cache(start_part)
level = 1 # keep track to prevent infinite loop in event there is a cycle in parts
current_part = self
cache[ [current_part.id, :complicated_calculation] ].delete
while ( (level <= 1 < @@MAX_PART_NESTING) && (current_part.parent_part)) {
current_part = current_part.parent_part)
cache[ [current_part.id, :complicated_calculation] ].delete
end
end
end
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
8388 次 |
| 最近记录: |