Class: ActiveSupport::Cache::RedisStore
- Inherits:
-
Store
- Object
- Store
- ActiveSupport::Cache::RedisStore
- Defined in:
- lib/active_support/cache/redis_store.rb
Instance Attribute Summary collapse
-
#data ⇒ Object
readonly
Returns the value of attribute data.
Instance Method Summary collapse
-
#clear ⇒ Object
Clear all the data from the store.
-
#decrement(key, amount = 1, options = {}) ⇒ Object
Decrement a key in the store.
-
#delete_matched(matcher, options = nil) ⇒ Object
Delete objects for matched keys.
-
#exist?(name, options = nil) ⇒ Boolean
fixed problem with invalid exists? method github.com/rails/rails/commit/cad2c8f5791d5bd4af0f240d96e00bae76eabd2f.
- #expire(key, ttl) ⇒ Object
- #fetch_multi(*names) ⇒ Object
-
#increment(key, amount = 1, options = {}) ⇒ Object
Increment a key in the store.
-
#initialize(*addresses) ⇒ RedisStore
constructor
Instantiate the store.
-
#read_multi(*names) ⇒ Object
Reads multiple keys from the cache using a single call to the servers for all keys.
- #reconnect ⇒ Object
- #stats ⇒ Object
- #with(&block) ⇒ Object
- #write(name, value, options = nil) ⇒ Object
Constructor Details
#initialize(*addresses) ⇒ RedisStore
Instantiate the store.
Example:
RedisStore.new
# => host: localhost, port: 6379, db: 0
RedisStore.new "example.com"
# => host: example.com, port: 6379, db: 0
RedisStore.new "example.com:23682"
# => host: example.com, port: 23682, db: 0
RedisStore.new "example.com:23682/1"
# => host: example.com, port: 23682, db: 1
RedisStore.new "example.com:23682/1/theplaylist"
# => host: example.com, port: 23682, db: 1, namespace: theplaylist
RedisStore.new "localhost:6379/0", "localhost:6380/0"
# => instantiate a cluster
RedisStore.new "localhost:6379/0", "localhost:6380/0", pool_size: 5, pool_timeout: 10
# => use a ConnectionPool
RedisStore.new "localhost:6379/0", "localhost:6380/0",
pool: ::ConnectionPool.new(size: 1, timeout: 1) { ::Redis::Store::Factory.create("localhost:6379/0") })
# => supply an existing connection pool (e.g. for use with redis-sentinel or redis-failover)
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/active_support/cache/redis_store.rb', line 36 def initialize(*addresses) @options = addresses.dup. addresses = addresses.map(&:dup) @data = if @options[:pool] raise "pool must be an instance of ConnectionPool" unless @options[:pool].is_a?(ConnectionPool) @pooled = true @options[:pool] elsif [:pool_size, :pool_timeout].any? { |key| @options.has_key?(key) } = {} [:size] = [:pool_size] if [:pool_size] [:timeout] = [:pool_timeout] if [:pool_timeout] @pooled = true ::ConnectionPool.new() { ::Redis::Store::Factory.create(*addresses) } else ::Redis::Store::Factory.create(*addresses) end super(@options) end |
Instance Attribute Details
#data ⇒ Object (readonly)
Returns the value of attribute data.
7 8 9 |
# File 'lib/active_support/cache/redis_store.rb', line 7 def data @data end |
Instance Method Details
#clear ⇒ Object
Clear all the data from the store.
212 213 214 215 216 |
# File 'lib/active_support/cache/redis_store.rb', line 212 def clear instrument(:clear, nil, nil) do with(&:flushdb) end end |
#decrement(key, amount = 1, options = {}) ⇒ Object
Decrement a key in the store
If the key doesn’t exist it will be initialized on 0. If the key exist but it isn’t a Fixnum it will be initialized on 0.
Example:
We have two objects in cache:
counter # => 23
rabbit # => #<Rabbit:0x5eee6c>
cache.decrement "counter"
cache.read "counter", :raw => true # => "22"
cache.decrement "counter", 2
cache.read "counter", :raw => true # => "20"
cache.decrement "a counter"
cache.read "a counter", :raw => true # => "-1"
cache.decrement "rabbit"
cache.read "rabbit", :raw => true # => "-1"
199 200 201 202 203 204 |
# File 'lib/active_support/cache/redis_store.rb', line 199 def decrement(key, amount = 1, = {}) = () instrument(:decrement, key, :amount => amount) do with{|c| c.decrby normalize_key(key, ), amount} end end |
#delete_matched(matcher, options = nil) ⇒ Object
Delete objects for matched keys.
Uses SCAN to iterate and collect matched keys only when both client and server supports it (Redis server >= 2.8.0, client >= 3.0.6)
Performance note: this operation can be dangerous for large production databases on Redis < 2.8.0, as it uses the Redis “KEYS” command, which is O(N) over the total number of keys in the database. Users of large Redis caches should avoid this method.
Example:
cache.delete_matched "rab*"
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/active_support/cache/redis_store.rb', line 80 def delete_matched(matcher, = nil) = () instrument(:delete_matched, matcher.inspect) do matcher = key_matcher(matcher, ) begin with do |store| supports_scan_each = store.respond_to?(:supports_redis_version?) && store.supports_redis_version?("2.8.0") && store.respond_to?(:scan_each) if supports_scan_each keys = store.scan_each(match: matcher).to_a else keys = store.keys(matcher) end !keys.empty? && store.del(*keys) end rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Redis::CannotConnectError raise if raise_errors? false end end end |
#exist?(name, options = nil) ⇒ Boolean
fixed problem with invalid exists? method github.com/rails/rails/commit/cad2c8f5791d5bd4af0f240d96e00bae76eabd2f
220 221 222 223 |
# File 'lib/active_support/cache/redis_store.rb', line 220 def exist?(name, = nil) res = super(name, ) res || false end |
#expire(key, ttl) ⇒ Object
206 207 208 209 |
# File 'lib/active_support/cache/redis_store.rb', line 206 def expire(key, ttl) = (nil) with { |c| c.expire normalize_key(key, ), ttl } end |
#fetch_multi(*names) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/active_support/cache/redis_store.rb', line 123 def fetch_multi(*names) return {} if names == [] results = read_multi(*names) = names. need_writes = {} fetched = names.inject({}) do |memo, name| memo[name] = results.fetch(name) do value = yield name need_writes[name] = value value end memo end with do |c| c.multi do need_writes.each do |name, value| write(name, value, ) end end end fetched end |
#increment(key, amount = 1, options = {}) ⇒ Object
Increment a key in the store.
If the key doesn’t exist it will be initialized on 0. If the key exist but it isn’t a Fixnum it will be initialized on 0.
Example:
We have two objects in cache:
counter # => 23
rabbit # => #<Rabbit:0x5eee6c>
cache.increment "counter"
cache.read "counter", :raw => true # => "24"
cache.increment "counter", 6
cache.read "counter", :raw => true # => "30"
cache.increment "a counter"
cache.read "a counter", :raw => true # => "1"
cache.increment "rabbit"
cache.read "rabbit", :raw => true # => "1"
171 172 173 174 175 176 |
# File 'lib/active_support/cache/redis_store.rb', line 171 def increment(key, amount = 1, = {}) = () instrument(:increment, key, :amount => amount) do with{|c| c.incrby normalize_key(key, ), amount} end end |
#read_multi(*names) ⇒ Object
Reads multiple keys from the cache using a single call to the servers for all keys. Options can be passed in the last argument.
Example:
cache.read_multi "rabbit", "white-rabbit"
cache.read_multi "rabbit", "white-rabbit", :raw => true
111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/active_support/cache/redis_store.rb', line 111 def read_multi(*names) return {} if names == [] = names. keys = names.map{|name| normalize_key(name, )} values = with { |c| c.mget(*keys) } values.map! { |v| v.is_a?(ActiveSupport::Cache::Entry) ? v.value : v } result = Hash[names.zip(values)] result.reject!{ |k,v| v.nil? } result end |
#reconnect ⇒ Object
237 238 239 |
# File 'lib/active_support/cache/redis_store.rb', line 237 def reconnect @data.reconnect if @data.respond_to?(:reconnect) end |
#stats ⇒ Object
225 226 227 |
# File 'lib/active_support/cache/redis_store.rb', line 225 def stats with(&:info) end |
#with(&block) ⇒ Object
229 230 231 232 233 234 235 |
# File 'lib/active_support/cache/redis_store.rb', line 229 def with(&block) if defined?(@pooled) && @pooled @data.with(&block) else block.call(@data) end end |
#write(name, value, options = nil) ⇒ Object
57 58 59 60 61 62 63 64 65 66 |
# File 'lib/active_support/cache/redis_store.rb', line 57 def write(name, value, = nil) = () instrument(:write, name, ) do |payload| entry = [:raw].present? ? value : Entry.new(value, ) if [:expires_in].present? && [:race_condition_ttl].present? && [:raw].blank? [:expires_in] = [:expires_in].to_f + [:race_condition_ttl].to_f end write_entry(normalize_key(name, ), entry, ) end end |