ArCache (This is outdated, please see 中文文档)
ArCache
is an modern cacheing library for ActiveRecord
inspired by cache-money and second_level_cache.
It works automatically by overridden ActiveRecord
related CURD code.
When executing standard ActiveRecord
query, it will first query the cache, and if there is none in the cache,
then query the database and write the result to the cache.
! WARNING: Please read these information before using
ArCache
.
Features
-
Low impact
: If your code strictly comply with the activerecord style, you don’t need to modify any code.(see more details) -
Read cache
: Automatically intercept ActiveRecord queries, then try to fetch data from cache. -
Write cache
: If the query is cacheable and the cached data is not exists, it will be automatically written to the cache after the query. -
Expire cache
: Automatically expire cache after updated/modified data. -
Iterative cache
: The cache version will be updated after table fields orArCache
switch changed. -
Shared cache
: The cache is not only used with ActiveRecord, you can easily use it in other places.(see examples)
Installation
Add this line to your application's Gemfile:
gem 'ar_cache'
And then execute:
bundle install
Post Installation
If is an rails
application:
rails generate ar_cache:install
Otherwise copy configuration and migration files to your application.
After that review the migrations then migrate:
rake db:migrate
Usage
ArCache
works automatically, so you don’t need to care about how to use the cache, just need to know how to skip and delete the cache.
Skip cache:
-
ArCache#skip_cache
, eg:
# All queries in the block will not use the cache.
ArCache.skip_cache { User.find(1) }
-
ActiveRecord::Persistence#reload
, eg:
User.find(1).reload
-
ActiveRecord::Relation#reload
, eg:
# When reload is called after the associated target has been loaded, the cache will be skipped.
User.where(id: 1).load.reload
-
ActiveRecord::Associations::Association#reload
, eg:
# When reload is called after the associated target has been loaded, the cache will be skipped.
user.association(:account).load_target.reload
Delete cache:
-
ArCache::Table
, eg:
User.ar_cache_table.delete(id...)
User.first.ar_cache_table.delete(id...)
Configuration
For configuration information, please see configuration file.
Cacheable query
If all the following conditions are met, ArCache will try to read the cache:
-
Use hash as
#where
parameter. - Query condition contains unique index.
- Condition of unique index is only one array or no array.
- No call
#select
or select value is table column. - No call
#order
or order value is table column and only one. - No call
#limit
or value of the unique index isn't array. - No call
#joins
,#left_joins
,#skip_query_cache!
,#explain
,#from
,#group
,#offset
,#lock
- ...
Cacheable example:
User.find(1) # support primary key cache
User.where(id: [1, 2]) # support multi-value unique index cache
User.where(email: 'foobar@gmail.com') # support sigle-column unique index cache
User.where(name: 'foobar', status: :active) # support multi-column unique index cache
User.includes(:account).where(id: [1, 2]) # support association preload cache
User.first.account # support association reader cach
The association cache support belongs_to and has_one, small amount of complex has_one(scope, through:, as:) don't support, then has_many cache support, please watch to future version.
Cache iteration
The following cases will cause cache iteration:
- Table field changes.
- Turn on
ArCache
or turn offArCache
. - Call
#upsert_all
method.
Notice: After iteration, all existing caches of the table will be expired!
How it works(Work in progress)
ArCache
works based on the unique index of the table.
Warning
- Prohibit the use of
#execute
update/delete operations! - Prohibit use
ActiveRecord
other underlying methods to directly update/delete data! (You is a fake activerecord user if this code appears) - Prohibit skip
ActiveRecord
directly update/delete data!
If you have to do this, please consider turning off ArCache.
Alternatives
There are some other gems implementations for ActiveRecord
cache such as:
However, ArCache
has some differences:
- It don’t depend with
ActiveRecord
callbacks, so don’t need to deal with dirty cache manually. - It cache real database data, so can use it's cache at other places.
- It can automatically handle cache iteration, so don't need to update cache version manually.
- It proxy standard ActiveRecord query, so don't need to modify the code and remember the additional api.
- The new data need to perform a query before the cache will take effect.
- The cache will not be updated after the data is updated, but the cache will be expired directly.
Development
After checking out the repo, run bin/setup
to install dependencies. Then, run rake test
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 the created tag, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/OuYangJinTing/ar_cache. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the ArCache
project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.