Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is ActiveSupport::Cache::Strategy::LocalCache used for?

In my production middleware stack in all environments I see this one-off instance:

use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x7f38095d>

I've experimented by removing everything I can think of related to caching, but I'm unable to figure out where it comes from.

What is it?

like image 245
John Bachir Avatar asked Jan 20 '26 01:01

John Bachir


2 Answers

In the abstract, it wraps another cache with an in-memory cache for the duration of a block, and then is cleared after the block.

In practice I believe it is used in Rails/Rack to wrap whatever cache you have configured (memcached, disk) with an in-memory cache which is cleared at the end of the request. The idea is that if you fetch the same cache key twice in one request, it will be cached in the wrapping LocalCache on the first request and will loaded from memory on the second request (instead of reaching out to the memcached server/disk again).

From the docs:

Caches that implement LocalCache will be backed by an in-memory cache for the duration of a block. Repeated calls to the cache for the same key will hit the in-memory cache for faster access.

Git History: https://github.com/rails/rails/commits/master/activesupport/lib/active_support/cache/strategy/local_cache.rb

RDoc: http://api.rubyonrails.org/classes/ActiveSupport/Cache/Strategy/LocalCache.html

like image 59
jshkol Avatar answered Jan 22 '26 16:01

jshkol


First, I'd like to show you some methods from official document.

ActiveSupport::Cache::DalliStore#with_local_cache

def with_local_cache
  use_temporary_local_cache(LocalStore.new) { yield }
end

def use_temporary_local_cache(temporary_cache)
  save_cache = LocalCacheRegistry.cache_for(local_cache_key)
  begin
    LocalCacheRegistry.set_cache_for(local_cache_key, temporary_cache)
    yield
  ensure
    LocalCacheRegistry.set_cache_for(local_cache_key, save_cache)
  end
end

def write(name, value, options=nil)
  options ||= {}
  name = expanded_key name

  instrument(:write, name, options) do |payload|
    with do |connection|
      options = options.merge(:connection => connection)
      write_entry(name, value, options)
    end
  end
end

def write_entry(key, entry, options) # :nodoc:
  local_cache.write_entry(key, entry, options) if local_cache
  super
end

And now, we use them in practice.

@cache = Rails.cache
@cache.with_local_cache do
   @cache.write('key', 'value')
end

If you combine the code above, you'll find that there should have two place which cached ('key', 'value') pairs. One is LocalCache, another is our @cache. It's purpose is declared in source code clearly.

Caches that implement LocalCache will be backed by an in-memory cache for the duration of a block. Repeated calls to the cache for the same key will hit the in-memory cache for faster access.

I hope this will do help for you!

like image 41
hiveer Avatar answered Jan 22 '26 16:01

hiveer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!