IdentityCache的缓存失效机制
IDC的更新机制基本上是靠after_commit :expire_cache来做的,它使得commit后自动删掉对应“前缀+id”的缓存
至于为什么要after_commit而非after_save、after_update,那是因为commit只会有一次,而且只在整个transaction成功后才有。如果删缓存后,transaction中接下来的某个对象不合格导致rollback而使数据库没更新,那么缓存就白删了
相关源码如下
identity_cache-0.5.1/lib/identity_cache/query_api.rb
module IdentityCache
module QueryAPI
extend ActiveSupport::Concern
included do |base|
base.after_commit :expire_cache
end
module ClassMethods
def fetch_by_id(id, options={})
# ...
IdentityCache.fetch(rails_cache_key(id)){ coder_from_record(object = resolve_cache_miss(id)) }
# ...
end
end
def expire_cache
expire_primary_index
expire_attribute_indexes
true
end
def expire_primary_index
return unless self.class.primary_cache_index_enabled
IdentityCache.logger.debug do
extra_keys =
if respond_to?(:updated_at)
old_updated_at = old_values_for_fields([:updated_at]).first
"expiring_last_updated_at=#{old_updated_at}"
else
""
end
"[IdentityCache] expiring=#{self.class.name} expiring_id=#{id} #{extra_keys}"
end
IdentityCache.cache.delete(primary_cache_index_key)
end
identity_cache-0.5.1/lib/identity_cache/cache_key_generation.rb
module IdentityCache
module CacheKeyGeneration
extend ActiveSupport::Concern
DEFAULT_NAMESPACE = "IDC:#{CACHE_VERSION}:".freeze
module ClassMethods
def rails_cache_key(id)
"#{prefixed_rails_cache_key}#{id}"
end
end
def primary_cache_index_key
self.class.rails_cache_key(id)
end