Stockpile is a simple cache written in Ruby backed by Redis. It has built in cache-stampede (also known as dog-piling) protection.
Can be used with any Ruby or Ruby on Rails project. Can be used as a replacement for existing Ruby on Rails cache.
Intended as a heavy usage cache to prevent concurrent execution of code when cache is expired that will lead to congestion collapse of your systems.
Upon caching serializes cached value using Oj gem. While reading value from cache will deserialize value from cache using same gem.
How it works
perform_cached method is invoked with a key and a block of code as
arguments Stockpile will attempt to fetch value from cache using given key. If
no value is returned it will set a lock deferring all other requests for given
key (for specified amount of time) and run provided block of code and storing
it's return value at the key. After that a lock will be released allowing other
requests to fetch their values from cache.
In case there is a cache miss and an active execution lock for a given key is
present request will go into slumber for 2 seconds (configurable by
STOCKPILE_SLUMBER environment variable or by calling
slumber method on
configuration object). During slumber request will keep trying to read value
from cache and if no result is returned during that time cache will be bypassed
and value will be computed by executing passed in block.
Add the following line to your Gemfile:
bundle from your shell.
To install gem manually run from your shell:
gem install stockpile_cache
Only requirement to run this gem is Redis. Other than that it is not dependant on any other framework or system.
The only thing you need to set up is URL of your Redis server. You can do this
by either setting
STOCKPILE_REDIS_URL environment variable or by executing
following code during runtime. For Ruby on Rails create
config/initializers/stockpile.rb file and put the following code in there:
Stockpile.configure do |configuration| configuration.redis_url = <REDIS_URL> end
There are two ways to configure Stockpile: using environment variables or invoking configuration block during runtime.
Following settings are supported:
||Redis connection pool size to share amongst the fibers or threads in your Ruby. Defaults to
||How long to wait for a connection from connection pool to become available (in seconds). Defaults to
||Time to keep execution lock alive (in seonds). Defaults to
||URL of your Redis server that will be used for caching. Defaults to
||(optional) Comma separated list of Sentinels IPs for Redis. Defaults to
||Timeout (in seconds) for stampede protection lock. After timeout passed in code will be executed instead of reading a value from cache. Defaults to
To use simply wrap your code into
Stockpile.perform_cached(key: 'meaning_of_life', ttl: 42) do 21 + 21 end
perform method accepts 3 named arguments:
||Pointer in cache by which a value will be either looked up or stored in cache once code provided in block is executed.|
||(optional) Time in seconds for which a cached value will be stored. Defaults to 300 seconds (5 minutes).|
||Block of code to execute; it's return value will be stored in cache.|
There is no timeout or rescue set for code you will be running through the cache. If you need to do either you have to handle it outside of Stockpile.
Locks are never set indefinitely and by default will expire after 10 seconds
allowing next request to trigger cache recalculation. Lock duration is
configurable by either setting
STOCKPILE_LOCK_EXPIRATION environment variable
or by calling
slumber method on configuration object.
While there is an active lock for the key each request trying to read that key
will wait in slumber for 2 seconds (configurable by
environment variable or by calling
slumber method on configuration object) and
will bypass cache after that if no value will be set in that time.
After checking out the repo, run
bin/setup to install dependencies. Then, run
rspec to run the tests. You can also run
bin/console for an interactive
prompt that will allow you to experiment.
To install this gem onto your local machine, run
bundle exec rake install. To
release a new version, update the version number in
version.rb, and then run
bundle exec rake release, which will create a git tag for the version, push
git commits and tags, and push the
.gem file to
Bug reports and pull requests are welcome on GitHub at https://github.com/ConvertKit/stockpile_cache. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the [Apache License Version 2.0] (http://www.apache.org/licenses/LICENSE-2.0).
Code of Conduct
Everyone interacting in the Stockpile project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.