|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
1 |
require 'memcache' |
| |
2 |
|
| |
3 |
module ActiveSupport |
| |
4 |
module Cache |
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
5 |
# A cache store implementation which stores data in Memcached: |
| |
6 |
# http://www.danga.com/memcached/ |
| |
7 |
# |
| |
8 |
# This is currently the most popular cache store for production websites. |
| |
9 |
# |
| |
10 |
# Special features: |
| |
11 |
# - Clustering and load balancing. One can specify multiple memcached servers, |
| |
12 |
# and MemCacheStore will load balance between all available servers. If a |
| |
13 |
# server goes down, then MemCacheStore will ignore it until it goes back |
| |
14 |
# online. |
| |
15 |
# - Time-based expiry support. See #write and the +:expires_in+ option. |
|
a53ad5bb
»
|
terrcin |
2009-01-15 |
Added in a local per reques...  |
16 |
# - Per-request in memory cache for all communication with the MemCache server(s). |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
17 |
class MemCacheStore < Store |
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
18 |
module Response # :nodoc: |
|
0d26e47b
»
|
jeremy |
2008-02-01 |
MemCacheStore#write and #de... |
19 |
STORED = "STORED\r\n" |
| |
20 |
NOT_STORED = "NOT_STORED\r\n" |
| |
21 |
EXISTS = "EXISTS\r\n" |
| |
22 |
NOT_FOUND = "NOT_FOUND\r\n" |
| |
23 |
DELETED = "DELETED\r\n" |
| |
24 |
end |
| |
25 |
|
|
e2ed1a1c
»
|
brynary |
2009-05-19 |
Allow MemCacheStore to be i... |
26 |
def self.build_mem_cache(*addresses) |
| |
27 |
addresses = addresses.flatten |
| |
28 |
options = addresses.extract_options! |
| |
29 |
addresses = ["localhost"] if addresses.empty? |
| |
30 |
MemCache.new(addresses, options) |
| |
31 |
end |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
32 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
33 |
# Creates a new MemCacheStore object, with the given memcached server |
| |
34 |
# addresses. Each address is either a host name, or a host-with-port string |
| |
35 |
# in the form of "host_name:port". For example: |
| |
36 |
# |
| |
37 |
# ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229") |
| |
38 |
# |
| |
39 |
# If no addresses are specified, then MemCacheStore will connect to |
| |
40 |
# localhost port 11211 (the default memcached port). |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
41 |
def initialize(*addresses) |
|
e2ed1a1c
»
|
brynary |
2009-05-19 |
Allow MemCacheStore to be i... |
42 |
if addresses.first.is_a?(MemCache) |
| |
43 |
@data = addresses.first |
| |
44 |
else |
| |
45 |
@data = self.class.build_mem_cache(*addresses) |
| |
46 |
end |
|
b08c9688
»
|
methodmissing |
2009-01-17 |
Decouple the local cache st...  |
47 |
|
| |
48 |
extend Strategy::LocalCache |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
49 |
end |
| |
50 |
|
|
29550cc9
»
|
Joe Van Dyk |
2009-02-02 |
Add ability to get multiple...  |
51 |
# Reads multiple keys from the cache. |
| |
52 |
def read_multi(*keys) |
| |
53 |
@data.get_multi keys |
| |
54 |
end |
| |
55 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
56 |
def read(key, options = nil) # :nodoc: |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
57 |
super |
|
b08c9688
»
|
methodmissing |
2009-01-17 |
Decouple the local cache st...  |
58 |
@data.get(key, raw?(options)) |
|
29938ba0
»
|
dhh |
2008-01-21 |
Log an error to the console... |
59 |
rescue MemCache::MemCacheError => e |
| |
60 |
logger.error("MemCacheError (#{e}): #{e.message}") |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
61 |
nil |
| |
62 |
end |
| |
63 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
64 |
# Writes a value to the cache. |
| |
65 |
# |
| |
66 |
# Possible options: |
| |
67 |
# - +:unless_exist+ - set to true if you don't want to update the cache |
| |
68 |
# if the key is already set. |
| |
69 |
# - +:expires_in+ - the number of seconds that this value may stay in |
| |
70 |
# the cache. See ActiveSupport::Cache::Store#write for an example. |
|
40f67639
»
|
dhh |
2008-02-07 |
Fix that the options hash c... |
71 |
def write(key, value, options = nil) |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
72 |
super |
|
9f07b1ed
»
|
tobi |
2008-04-29 |
By default rails will updat... |
73 |
method = options && options[:unless_exist] ? :add : :set |
|
4b63c270
»
|
dougbarth |
2008-10-09 |
Bring MemCacheStore and Com... |
74 |
# memcache-client will break the connection if you send it an integer |
| |
75 |
# in raw mode, so we convert it to a string to be sure it continues working. |
| |
76 |
value = value.to_s if raw?(options) |
|
0d26e47b
»
|
jeremy |
2008-02-01 |
MemCacheStore#write and #de... |
77 |
response = @data.send(method, key, value, expires_in(options), raw?(options)) |
| |
78 |
response == Response::STORED |
|
29938ba0
»
|
dhh |
2008-01-21 |
Log an error to the console... |
79 |
rescue MemCache::MemCacheError => e |
| |
80 |
logger.error("MemCacheError (#{e}): #{e.message}") |
|
0d26e47b
»
|
jeremy |
2008-02-01 |
MemCacheStore#write and #de... |
81 |
false |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
82 |
end |
| |
83 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
84 |
def delete(key, options = nil) # :nodoc: |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
85 |
super |
|
0d26e47b
»
|
jeremy |
2008-02-01 |
MemCacheStore#write and #de... |
86 |
response = @data.delete(key, expires_in(options)) |
| |
87 |
response == Response::DELETED |
|
29938ba0
»
|
dhh |
2008-01-21 |
Log an error to the console... |
88 |
rescue MemCache::MemCacheError => e |
| |
89 |
logger.error("MemCacheError (#{e}): #{e.message}") |
|
0d26e47b
»
|
jeremy |
2008-02-01 |
MemCacheStore#write and #de... |
90 |
false |
|
99860b72
»
|
josevalim |
2008-05-16 |
Add fragment_exist? and exi... |
91 |
end |
| |
92 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
93 |
def exist?(key, options = nil) # :nodoc: |
|
99860b72
»
|
josevalim |
2008-05-16 |
Add fragment_exist? and exi... |
94 |
# Doesn't call super, cause exist? in memcache is in fact a read |
| |
95 |
# But who cares? Reading is very fast anyway |
|
a53ad5bb
»
|
terrcin |
2009-01-15 |
Added in a local per reques...  |
96 |
# Local cache is checked first, if it doesn't know then memcache itself is read from |
|
b08c9688
»
|
methodmissing |
2009-01-17 |
Decouple the local cache st...  |
97 |
!read(key, options).nil? |
|
99860b72
»
|
josevalim |
2008-05-16 |
Add fragment_exist? and exi... |
98 |
end |
|
fef82759
»
|
tobi |
2008-04-29 |
Implement increment/decreme... |
99 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
100 |
def increment(key, amount = 1) # :nodoc: |
|
fef82759
»
|
tobi |
2008-04-29 |
Implement increment/decreme... |
101 |
log("incrementing", key, amount) |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
102 |
|
| |
103 |
response = @data.incr(key, amount) |
|
b08c9688
»
|
methodmissing |
2009-01-17 |
Decouple the local cache st...  |
104 |
response == Response::NOT_FOUND ? nil : response |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
105 |
rescue MemCache::MemCacheError |
|
fef82759
»
|
tobi |
2008-04-29 |
Implement increment/decreme... |
106 |
nil |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
107 |
end |
| |
108 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
109 |
def decrement(key, amount = 1) # :nodoc: |
|
fef82759
»
|
tobi |
2008-04-29 |
Implement increment/decreme... |
110 |
log("decrement", key, amount) |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
111 |
response = @data.decr(key, amount) |
|
b08c9688
»
|
methodmissing |
2009-01-17 |
Decouple the local cache st...  |
112 |
response == Response::NOT_FOUND ? nil : response |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
113 |
rescue MemCache::MemCacheError |
|
fef82759
»
|
tobi |
2008-04-29 |
Implement increment/decreme... |
114 |
nil |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
115 |
end |
| |
116 |
|
|
b047929c
»
|
lifo |
2008-11-01 |
Merge with docrails |
117 |
def delete_matched(matcher, options = nil) # :nodoc: |
|
a53ad5bb
»
|
terrcin |
2009-01-15 |
Added in a local per reques...  |
118 |
# don't do any local caching at present, just pass |
| |
119 |
# through and let the error happen |
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
120 |
super |
| |
121 |
raise "Not supported by Memcache" |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
122 |
end |
| |
123 |
|
|
4c307718
»
|
jeremy |
2008-02-20 |
Add #clear to mem_cache_sto... |
124 |
def clear |
| |
125 |
@data.flush_all |
|
7ae2105d
»
|
josh |
2008-07-16 |
MemCacheStore#decrement sho... |
126 |
end |
| |
127 |
|
|
09517e3a
»
|
tobi |
2008-04-29 |
Allow access to mem_cache_s... |
128 |
def stats |
| |
129 |
@data.stats |
|
4c307718
»
|
jeremy |
2008-02-20 |
Add #clear to mem_cache_sto... |
130 |
end |
| |
131 |
|
|
2a9ad9cc
»
|
dhh |
2008-01-03 |
Moved the caching stores fr... |
132 |
private |
| |
133 |
def expires_in(options) |
| |
134 |
(options && options[:expires_in]) || 0 |
| |
135 |
end |
| |
136 |
|
| |
137 |
def raw?(options) |
| |
138 |
options && options[:raw] |
| |
139 |
end |
| |
140 |
end |
| |
141 |
end |
| |
142 |
end |