README.md in second_level_cache-1.6.0 vs README.md in second_level_cache-1.6.1

- old
+ new

@@ -1,17 +1,19 @@ # SecondLevelCache +[![Gem Version](https://badge.fury.io/rb/second_level_cache.png)](http://badge.fury.io/rb/second_level_cache) +[![Dependency Status](https://gemnasium.com/csdn-dev/second_level_cache.png)](https://gemnasium.com/csdn-dev/second_level_cache) +[![Build Status](https://travis-ci.org/csdn-dev/second_level_cache.png?branch=master)](https://travis-ci.org/csdn-dev/second_level_cache) +[![Code Climate](https://codeclimate.com/github/csdn-dev/second_level_cache.png)](https://codeclimate.com/github/csdn-dev/second_level_cache) + SecondLevelCache is a write-through and read-through caching library inspired by Cache Money and cache_fu, support only Rails3 and ActiveRecord. Read-Through: Queries by ID, like `current_user.articles.find(params[:id])`, will first look in cache store and then look in the database for the results of that query. If there is a cache miss, it will populate the cache. Write-Through: As objects are created, updated, and deleted, all of the caches are automatically kept up-to-date and coherent. -## Risk -SecondLevelCache is not fully test and verify in production enviroment right now. Use it at your own risk. - ## Install In your gem file: ```ruby @@ -47,42 +49,117 @@ ```ruby user = User.find 1 user.second_level_cache_key # We will get the key looks like "slc/user/1/0" ``` +Expires cache: + +```ruby +user = User.find(1) +user.expire_second_level_cache +``` +or expires cache using class method: +```ruby +User.expire_second_level_cache(1) +``` + Disable SecondLevelCache: ```ruby - User.without_second_level_cache do - user = User.find 1 - # ... - end +User.without_second_level_cache do + user = User.find 1 + # ... +end ``` Only `SELECT *` query will be cached: ```ruby - # this query will NOT be cached - User.select("id, name").find(1) +# this query will NOT be cached +User.select("id, name").find(1) ``` Notice: * SecondLevelCache cache by model name and id, so only find_one query will work. -* only equal conditions query WILL get cache; and SQL string query like `User.where("name = 'Hooopo'").find(1)` WILL NOT work. +* Only equal conditions query WILL get cache; and SQL string query like `User.where("name = 'Hooopo'").find(1)` WILL NOT work. +* SecondLevelCache sync cache after transaction commit: -## configure +```ruby +# user and account's write_second_level_cache operation will invoke after the logger. +ActiveRecord::Base.transaction do + user.save + account.save + Rails.logger.info "info" +end # <- Cache write -cache_store: Default is Rails.cache -logger: Default is Rails.logger -cache_key_prefix: Avoid cache key conflict with other application, Default is 'slc' +# if you want to do something after user and account's write_second_level_cache operation, do this way: +ActiveRecord::Base.transaction do + user.save + account.save +end # <- Cache write +Rails.logger.info "info" +``` -You can config like this: +## Configure +In production env, we recommend to use [Dalli](https://github.com/mperham/dalli) as Rails cache store. ```ruby -# config/initializers/second_level_cache.rb -SecondLevelCache.configure do |config| - config.cache_store = ActiveSupport::Cache::MemoryStore.new - config.logger = Logger.new($stdout) - config.cache_key_prefix = 'domain' + config.cache_store = [:dalli_store, APP_CONFIG["memcached_host"], {:namespace => "ns", :compress => true}] +``` + +## Tips: + +* When you want to clear only second level cache apart from other cache for example fragment cache in cache store, +you can only change the `cache_key_prefix`: + +```ruby +SecondLevelCache.configure.cache_key_prefix = "slc1" +``` +* When schema of your model changed, just change the `version` of the speical model, avoding clear all the cache. + +```ruby +class User < ActiveRecord::Base + acts_as_cached(:version => 2, :expires_in => 1.week) end ``` + +* It provides a great feature, not hits db when fetching record via unique key(not primary key). + +```ruby +# this will fetch from cache +user = User.fetch_by_uniq_key("hooopo", :nick_name) + +# this also fetch from cache +user = User.fetch_by_uniq_key!("hooopo", :nick_name) # this will raise `ActiveRecord::RecordNotFound` Exception when nick name not exists. +``` + +## Contributors + +* [chloerei](https://github.com/chloerei) +* [reyesyang](https://github.com/reyesyang) +* [hooopo](https://github.com/hooopo) +* [sishen](https://github.com/sishen) + +## License + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +