Module: IdentityCache
- Extended by:
- ActiveSupport::Concern, CacheHash
- Includes:
- WithPrimaryIndex
- Defined in:
- lib/identity_cache.rb,
lib/identity_cache/cached.rb,
lib/identity_cache/encoder.rb,
lib/identity_cache/railtie.rb,
lib/identity_cache/version.rb,
lib/identity_cache/query_api.rb,
lib/identity_cache/cache_hash.rb,
lib/identity_cache/expiry_hook.rb,
lib/identity_cache/cache_fetcher.rb,
lib/identity_cache/cache_key_loader.rb,
lib/identity_cache/cached/attribute.rb,
lib/identity_cache/fallback_fetcher.rb,
lib/identity_cache/record_not_found.rb,
lib/identity_cache/should_use_cache.rb,
lib/identity_cache/cached/belongs_to.rb,
lib/identity_cache/cached/prefetcher.rb,
lib/identity_cache/configuration_dsl.rb,
lib/identity_cache/belongs_to_caching.rb,
lib/identity_cache/cache_invalidation.rb,
lib/identity_cache/cached/association.rb,
lib/identity_cache/load_strategy/lazy.rb,
lib/identity_cache/with_primary_index.rb,
lib/identity_cache/load_strategy/eager.rb,
lib/identity_cache/mem_cache_store_cas.rb,
lib/identity_cache/cache_key_generation.rb,
lib/identity_cache/cached/primary_index.rb,
lib/identity_cache/memoized_cache_proxy.rb,
lib/identity_cache/without_primary_index.rb,
lib/identity_cache/cached/attribute_by_one.rb,
lib/identity_cache/parent_model_expiration.rb,
lib/identity_cache/cached/embedded_fetching.rb,
lib/identity_cache/cached/recursive/has_one.rb,
lib/identity_cache/cached/reference/has_one.rb,
lib/identity_cache/cached/attribute_by_multi.rb,
lib/identity_cache/cached/recursive/has_many.rb,
lib/identity_cache/cached/reference/has_many.rb,
lib/identity_cache/load_strategy/load_request.rb,
lib/identity_cache/cached/recursive/association.rb,
lib/identity_cache/cached/reference/association.rb,
lib/identity_cache/load_strategy/multi_load_request.rb
Defined Under Namespace
Modules: BelongsToCaching, CacheHash, CacheInvalidation, CacheKeyGeneration, ConfigurationDSL, LoadStrategy, MemCacheStoreCAS, QueryAPI, ShouldUseCache, WithPrimaryIndex, WithoutPrimaryIndex Classes: AlreadyIncludedError, AssociationError, CacheFetcher, DerivedModelError, FallbackFetcher, InverseAssociationError, LockWaitTimeout, MemoizedCacheProxy, NestedDeferredCacheExpirationBlockError, NestedDeferredParentBlockError, Railtie, RecordNotFound, UnsupportedAssociationError, UnsupportedScopeError
Constant Summary collapse
- CACHED_NIL =
:idc_cached_nil
- BATCH_SIZE =
1000
- DELETED =
:idc_cached_deleted
- DELETED_TTL =
1000
- VERSION =
"1.6.3"
- CACHE_VERSION =
8
Constants included from CacheInvalidation
CacheInvalidation::CACHE_KEY_NAMES
Constants included from CacheKeyGeneration
CacheKeyGeneration::DEFAULT_NAMESPACE
Class Attribute Summary collapse
- .fetch_read_only_records ⇒ Object
- .logger ⇒ Object
-
.readonly ⇒ Object
Returns the value of attribute readonly.
Class Method Summary collapse
-
.append_features(base) ⇒ Object
:nodoc:.
- .cache ⇒ Object
-
.cache_backend=(cache_adaptor) ⇒ Object
Sets the cache adaptor IdentityCache will be using.
- .deprecator ⇒ Object
- .eager_load! ⇒ Object
-
.fetch(key, cache_fetcher_options = {}) ⇒ Object
Cache retrieval and miss resolver primitive; given a key it will try to retrieve the associated value from the cache otherwise it will return the value of the execution of the block.
-
.fetch_multi(*keys) ⇒ Object
Same as
fetch
, except that it will try a collection of keys, using the multiget operation of the cache adaptor. - .map_cached_nil_for(value) ⇒ Object
-
.should_fill_cache? ⇒ Boolean
:nodoc:.
- .unmap_cached_nil_for(value) ⇒ Object
-
.with_deferred_expiration ⇒ Object
Executes a block with deferred cache expiration, ensuring that the records’ (parent, children and attributes) cache expiration is deferred until the block completes.
-
.with_deferred_parent_expiration ⇒ Object
Executes a block with deferred parent expiration, ensuring that the parent records’ cache expiration is deferred until the block completes.
- .with_fetch_read_only_records(value = true) ⇒ Object
Instance Method Summary collapse
-
#should_use_cache? ⇒ Boolean
:nodoc:.
Methods included from CacheHash
Methods included from WithPrimaryIndex
#expire_cache, #expire_primary_index, #primary_cache_index_key
Methods included from CacheInvalidation
Methods included from QueryAPI
#_run_commit_callbacks, #expire_cache, #was_new_record?
Methods included from CacheKeyGeneration
denormalized_schema_hash, denormalized_schema_string, schema_to_string
Class Attribute Details
.fetch_read_only_records ⇒ Object
308 309 310 311 312 313 |
# File 'lib/identity_cache.rb', line 308 def fetch_read_only_records v = Thread.current[:identity_cache_fetch_read_only_records] return v unless v.nil? @fetch_read_only_records end |
.logger ⇒ Object
114 115 116 |
# File 'lib/identity_cache.rb', line 114 def logger @logger || Rails.logger end |
.readonly ⇒ Object
Returns the value of attribute readonly.
87 88 89 |
# File 'lib/identity_cache.rb', line 87 def readonly @readonly end |
Class Method Details
.append_features(base) ⇒ Object
:nodoc:
90 91 92 93 94 |
# File 'lib/identity_cache.rb', line 90 def append_features(base) # :nodoc: raise AlreadyIncludedError if base.include?(IdentityCache) super end |
.cache ⇒ Object
110 111 112 |
# File 'lib/identity_cache.rb', line 110 def cache @cache ||= MemoizedCacheProxy.new end |
.cache_backend=(cache_adaptor) ⇒ Object
Sets the cache adaptor IdentityCache will be using
Parameters
cache_adaptor
- A ActiveSupport::Cache::Store
102 103 104 105 106 107 108 |
# File 'lib/identity_cache.rb', line 102 def cache_backend=(cache_adaptor) if defined?(@cache) cache.cache_backend = cache_adaptor else @cache = MemoizedCacheProxy.new(cache_adaptor) end end |
.deprecator ⇒ Object
319 320 321 |
# File 'lib/identity_cache.rb', line 319 def deprecator @deprecator ||= ActiveSupport::Deprecation.new("1.7.0", "IdentityCache") end |
.eager_load! ⇒ Object
315 316 317 |
# File 'lib/identity_cache.rb', line 315 def eager_load! ParentModelExpiration.install_all_pending_parent_expiry_hooks end |
.fetch(key, cache_fetcher_options = {}) ⇒ Object
Cache retrieval and miss resolver primitive; given a key it will try to retrieve the associated value from the cache otherwise it will return the value of the execution of the block.
Parameters
key
A cache key string cache_fetcher_options
A hash of options to pass to the cache backend
163 164 165 166 167 168 169 170 171 |
# File 'lib/identity_cache.rb', line 163 def fetch(key, = {}) if should_use_cache? unmap_cached_nil_for(cache.fetch(key, ) do map_cached_nil_for(yield) end) else yield end end |
.fetch_multi(*keys) ⇒ Object
Same as fetch
, except that it will try a collection of keys, using the multiget operation of the cache adaptor.
Parameters
keys
A collection or array of key strings
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/identity_cache.rb', line 186 def fetch_multi(*keys) keys.flatten!(1) return {} if keys.empty? result = if should_use_cache? fetch_in_batches(keys.uniq) do |missed_keys| results = yield missed_keys results.map { |e| map_cached_nil_for(e) } end else results = yield keys Hash[keys.zip(results)] end result.each do |key, value| result[key] = unmap_cached_nil_for(value) end result end |
.map_cached_nil_for(value) ⇒ Object
173 174 175 |
# File 'lib/identity_cache.rb', line 173 def map_cached_nil_for(value) value.nil? ? IdentityCache::CACHED_NIL : value end |
.should_fill_cache? ⇒ Boolean
:nodoc:
118 119 120 |
# File 'lib/identity_cache.rb', line 118 def should_fill_cache? # :nodoc: !readonly end |
.unmap_cached_nil_for(value) ⇒ Object
177 178 179 |
# File 'lib/identity_cache.rb', line 177 def unmap_cached_nil_for(value) value == IdentityCache::CACHED_NIL ? nil : value end |
.with_deferred_expiration ⇒ Object
Executes a block with deferred cache expiration, ensuring that the records’ (parent, children and attributes) cache expiration is deferred until the block completes. When the block completes, it issues delete_multi calls for all the records and attributes that were marked for expiration.
Parameters:
No parameters.
Raises:
NestedDeferredCacheExpirationBlockError if a deferred cache expiration block is already active.
Yield:
Runs the provided block with deferred cache expiration.
Returns:
The result of executing the provided block.
Ensures:
Cleans up thread-local variables related to deferred cache expiration regardless of whether the block raises an exception.
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/identity_cache.rb', line 269 def with_deferred_expiration raise NestedDeferredCacheExpirationBlockError if Thread.current[:idc_deferred_expiration] if Thread.current[:idc_deferred_parent_expiration] deprecator.deprecation_warning("`with_deferred_parent_expiration`") end Thread.current[:idc_deferred_expiration] = true Thread.current[:idc_records_to_expire] = Set.new Thread.current[:idc_attributes_to_expire] = Set.new result = yield Thread.current[:idc_deferred_expiration] = nil if Thread.current[:idc_records_to_expire].any? IdentityCache.cache.delete_multi( Thread.current[:idc_records_to_expire] ) end if Thread.current[:idc_attributes_to_expire].any? IdentityCache.cache.delete_multi( Thread.current[:idc_attributes_to_expire] ) end result ensure Thread.current[:idc_deferred_expiration] = nil Thread.current[:idc_records_to_expire].clear Thread.current[:idc_attributes_to_expire].clear end |
.with_deferred_parent_expiration ⇒ Object
Executes a block with deferred parent expiration, ensuring that the parent records’ cache expiration is deferred until the block completes. When the block completes, it triggers expiration of the primary index for the parent records. Raises a NestedDeferredParentBlockError if a deferred parent expiration block is already active on the current thread.
Parameters:
No parameters.
Raises:
NestedDeferredParentBlockError if a deferred parent expiration block is already active.
Yield:
Runs the provided block with deferred parent expiration.
Returns:
The result of executing the provided block.
Ensures:
Cleans up thread-local variables related to deferred parent expiration regardless of whether the block raises an exception.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/identity_cache.rb', line 228 def with_deferred_parent_expiration raise NestedDeferredParentBlockError if Thread.current[:idc_deferred_parent_expiration] if Thread.current[:idc_deferred_expiration] deprecator.deprecation_warning("`with_deferred_parent_expiration`") end Thread.current[:idc_deferred_parent_expiration] = true Thread.current[:idc_parent_records_for_cache_expiry] = Set.new result = yield Thread.current[:idc_deferred_parent_expiration] = nil Thread.current[:idc_parent_records_for_cache_expiry].each(&:expire_primary_index) result ensure Thread.current[:idc_deferred_parent_expiration] = nil Thread.current[:idc_parent_records_for_cache_expiry]&.clear end |
.with_fetch_read_only_records(value = true) ⇒ Object
300 301 302 303 304 305 306 |
# File 'lib/identity_cache.rb', line 300 def with_fetch_read_only_records(value = true) old_value = Thread.current[:identity_cache_fetch_read_only_records] Thread.current[:identity_cache_fetch_read_only_records] = value yield ensure Thread.current[:identity_cache_fetch_read_only_records] = old_value end |
Instance Method Details
#should_use_cache? ⇒ Boolean
:nodoc:
140 141 142 143 144 145 |
# File 'lib/identity_cache.rb', line 140 def should_use_cache? # :nodoc: ActiveRecord::Base.connection_handler.connection_pool_list(ActiveRecord::Base.current_role).none? do |pool| pool.active_connection? && pool.active_connection.current_transaction.joinable? end end |