Class: Memcache

Inherits:
Object show all
Defined in:
lib/memcache.rb,
lib/memcache/server.rb,
lib/memcache/migration.rb,
lib/memcache/pg_server.rb,
lib/memcache/null_server.rb,
lib/memcache/local_server.rb,
lib/memcache/segmented_server.rb

Defined Under Namespace

Classes: LocalServer, Migration, NullServer, PGServer, Pool, SegmentedServer, Server

Constant Summary collapse

VERSION =
'0.9.0'
DEFAULT_EXPIRY =
0
LOCK_TIMEOUT =
5
WRITE_LOCK_WAIT =
0.001

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts) ⇒ Memcache



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/memcache.rb', line 17

def initialize(opts)
  @readonly          = opts[:readonly]
  @default_expiry    = opts[:default_expiry] || DEFAULT_EXPIRY
  @default_namespace = opts[:namespace]
  default_server = opts[:segment_large_values] ? SegmentedServer : Server

  @servers = (opts[:servers] || [ opts[:server] ]).collect do |server|
    case server
    when Hash
      server = default_server.new(server)
    when String
      host, port = server.split(':')
      server = default_server.new(:host => host, :port => port)
    when Class
      server = server.new
    end
    server.strict_reads = true if opts[:strict_reads] and server.respond_to?(:strict_reads=)
    server
  end
end

Instance Attribute Details

#default_expiryObject (readonly)

Returns the value of attribute default_expiry.



15
16
17
# File 'lib/memcache.rb', line 15

def default_expiry
  @default_expiry
end

#default_namespaceObject (readonly)

Returns the value of attribute default_namespace.



15
16
17
# File 'lib/memcache.rb', line 15

def default_namespace
  @default_namespace
end

#serversObject (readonly)

Returns the value of attribute servers.



15
16
17
# File 'lib/memcache.rb', line 15

def servers
  @servers
end

Class Method Details

.poolObject



356
357
358
# File 'lib/memcache.rb', line 356

def self.pool
  @@cache_pool ||= Pool.new
end

Instance Method Details

#[]=(key, value) ⇒ Object



267
268
269
# File 'lib/memcache.rb', line 267

def []=(key, value)
  set(key, value)
end

#add(key, value, opts = {}) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/memcache.rb', line 101

def add(key, value, opts = {})
  raise 'opts must be hash' unless opts.kind_of?(Hash)

  expiry = opts[:expiry] || default_expiry
  key    = cache_key(key)
  data   = marshal(value, opts)
  server(key).add(key, data, expiry, opts[:flags]) && value
end

#append(key, value) ⇒ Object



128
129
130
131
# File 'lib/memcache.rb', line 128

def append(key, value)
  key = cache_key(key)
  server(key).append(key, value)
end

#cas(key, value, opts = {}) ⇒ Object



119
120
121
122
123
124
125
126
# File 'lib/memcache.rb', line 119

def cas(key, value, opts = {})
  raise 'opts must be hash' unless opts.kind_of?(Hash)

  expiry = opts[:expiry] || default_expiry
  key    = cache_key(key)
  data   = marshal(value, opts)
  server(key).cas(key, data, opts[:cas], expiry, opts[:flags]) && value
end

#count(key) ⇒ Object



138
139
140
141
# File 'lib/memcache.rb', line 138

def count(key)
  key = cache_key(key)
  server(key).get(key).to_i
end

#decr(key, amount = 1) ⇒ Object



151
152
153
154
155
156
157
# File 'lib/memcache.rb', line 151

def decr(key, amount = 1)
  key = cache_key(key)
  server(key).decr(key, amount) || begin
    server(key).add(key, '0')
    0 # Cannot decrement below zero.
  end
end

#delete(key) ⇒ Object



237
238
239
240
# File 'lib/memcache.rb', line 237

def delete(key)
  key = cache_key(key)
  server(key).delete(key)
end

#flush_all(opts = {}) ⇒ Object Also known as: clear



242
243
244
245
246
247
248
249
250
# File 'lib/memcache.rb', line 242

def flush_all(opts = {})
  delay    = opts[:delay].to_i
  interval = opts[:interval].to_i

  servers.each do |server|
    server.flush_all(delay)
    delay += interval
  end
end

#get(keys, opts = {}) ⇒ Object Also known as: []



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/memcache.rb', line 65

def get(keys, opts = {})
  raise 'opts must be hash' unless opts.kind_of?(Hash)

  if keys.kind_of?(Array)
    multi_get(keys, opts)
  else
    key = cache_key(keys)

    if opts[:expiry]
      value = server(key).gets(key)
      server(key).cas(key, value, value.memcache_cas, opts[:expiry]) if value
    else
      value = server(key).get(key, opts[:cas])
    end
    unmarshal(value, opts)
  end
end

#get_or_add(key, *args) ⇒ Object



168
169
170
171
172
173
174
175
176
177
# File 'lib/memcache.rb', line 168

def get_or_add(key, *args)
  # Pseudo-atomic get and update.
  if block_given?
    opts = args[0] || {}
    get(key) || add(key, yield, opts) || get(key)
  else
    opts = args[1] || {}
    get(key) || add(key, args[0], opts) || get(key)
  end
end

#get_or_set(key, *args) ⇒ Object



179
180
181
182
183
184
185
186
187
# File 'lib/memcache.rb', line 179

def get_or_set(key, *args)
  if block_given?
    opts = args[0] || {}
    get(key) || set(key, yield, opts)
  else
    opts = args[1] || {}
    get(key) || set(key, args[0], opts)
  end
end

#get_some(keys, opts = {}) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/memcache.rb', line 189

def get_some(keys, opts = {})
  keys = keys.collect {|key| key.to_s}

  records = opts[:disable] ? {} : self.get(keys, opts)
  if opts[:validation]
    records.delete_if do |key, value|
      not opts[:validation].call(key, value)
    end
  end

  keys_to_fetch = keys - records.keys
  method = opts[:overwrite] ? :set : :add
  if keys_to_fetch.any?
    yield(keys_to_fetch).each do |key, value|
      self.send(method, key, value, opts) unless opts[:disable] or opts[:disable_write]
      records[key] = value
    end
  end
  records
end

#in_namespace(namespace) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/memcache.rb', line 54

def in_namespace(namespace)
  # Temporarily change the namespace for convenience.
  begin
    old_namespace = self.namespace
    self.namespace = "#{old_namespace}#{namespace}"
    yield
  ensure
    self.namespace = old_namespace
  end
end

#incr(key, amount = 1) ⇒ Object



143
144
145
146
147
148
149
# File 'lib/memcache.rb', line 143

def incr(key, amount = 1)
  key = cache_key(key)
  server(key).incr(key, amount) || begin
    server(key).add(key, '0')
    server(key).incr(key, amount)
  end
end

#inspectObject



38
39
40
# File 'lib/memcache.rb', line 38

def inspect
  "<Memcache: %d servers, ns: %p, ro: %p>" % [@servers.length, namespace, @readonly]
end

#lock(key, opts = {}) ⇒ Object



210
211
212
213
214
# File 'lib/memcache.rb', line 210

def lock(key, opts = {})
  # Returns false if the lock already exists.
  expiry = opts[:expiry] || LOCK_TIMEOUT
  add(lock_key(key), Socket.gethostname, :expiry => expiry, :raw => true)
end

#lock_key(key) ⇒ Object



229
230
231
# File 'lib/memcache.rb', line 229

def lock_key(key)
  "lock:#{key}"
end

#locked?(key) ⇒ Boolean



233
234
235
# File 'lib/memcache.rb', line 233

def locked?(key)
  get(lock_key(key), :raw => true)
end

#namespaceObject



42
43
44
# File 'lib/memcache.rb', line 42

def namespace
  @namespace || default_namespace
end

#namespace=(namespace) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/memcache.rb', line 46

def namespace=(namespace)
  if default_namespace == namespace
    @namespace = nil
  else
    @namespace = namespace
  end
end

#prepend(key, value) ⇒ Object



133
134
135
136
# File 'lib/memcache.rb', line 133

def prepend(key, value)
  key = cache_key(key)
  server(key).prepend(key, value)
end

#read(keys, opts = {}) ⇒ Object



83
84
85
# File 'lib/memcache.rb', line 83

def read(keys, opts = {})
  get(keys, opts.merge(:raw => true))
end

#replace(key, value, opts = {}) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/memcache.rb', line 110

def replace(key, value, opts = {})
  raise 'opts must be hash' unless opts.kind_of?(Hash)

  expiry = opts[:expiry] || default_expiry
  key    = cache_key(key)
  data   = marshal(value, opts)
  server(key).replace(key, data, expiry, opts[:flags]) && value
end

#resetObject



252
253
254
# File 'lib/memcache.rb', line 252

def reset
  servers.each {|server| server.close}
end

#set(key, value, opts = {}) ⇒ Object



87
88
89
90
91
92
93
94
95
# File 'lib/memcache.rb', line 87

def set(key, value, opts = {})
  raise 'opts must be hash' unless opts.kind_of?(Hash)

  expiry = opts[:expiry] || default_expiry
  key    = cache_key(key)
  data   = marshal(value, opts)
  server(key).set(key, data, expiry, opts[:flags])
  value
end

#statsObject



256
257
258
259
260
261
262
# File 'lib/memcache.rb', line 256

def stats
  stats = {}
  servers.each do |server|
    stats[server.name] = server.stats
  end
  stats
end

#unlock(key) ⇒ Object



216
217
218
# File 'lib/memcache.rb', line 216

def unlock(key)
  delete(lock_key(key))
end

#update(key, opts = {}) ⇒ Object



159
160
161
162
163
164
165
166
# File 'lib/memcache.rb', line 159

def update(key, opts = {})
  value = get(key, :cas => true)
  if value
    cas(key, yield(value), opts.merge!(:cas => value.memcache_cas))
  else
    add(key, yield(value), opts)
  end
end

#with_lock(key, opts = {}) ⇒ Object



220
221
222
223
224
225
226
227
# File 'lib/memcache.rb', line 220

def with_lock(key, opts = {})
  until lock(key) do
    return if opts[:ignore]
    sleep(WRITE_LOCK_WAIT) # just wait
  end
  yield
  unlock(key) unless opts[:keep]
end

#write(key, value, opts = {}) ⇒ Object



97
98
99
# File 'lib/memcache.rb', line 97

def write(key, value, opts = {})
  set(key, value, opts.merge(:raw => true))
end