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 orArCacheswitch 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 installPost Installation
If is an rails application:
rails generate ar_cache:installOtherwise copy configuration and migration files to your application.
After that review the migrations then migrate:
rake db:migrateUsage
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.reloadDelete 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
#whereparameter. - Query condition contains unique index.
- Condition of unique index is only one array or no array.
- No call
#selector select value is table column. - No call
#orderor order value is table column and only one. - No call
#limitor 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 cachThe 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
ArCacheor turn offArCache. - Call
#upsert_allmethod.
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
#executeupdate/delete operations! - Prohibit use
ActiveRecordother underlying methods to directly update/delete data! (You is a fake activerecord user if this code appears) - Prohibit skip
ActiveRecorddirectly 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
ActiveRecordcallbacks, 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.