Class: ESI::MemcachedCache

Inherits:
Cache
  • Object
show all
Includes:
Log
Defined in:
lib/esi/cache.rb

Overview

A memcache cache store. Uses the memcached ruby client, see => seattlerb.rubyforge.org/memcache-client/ and www.danga.com/memcached/

There are few issues to consider about providing a memcached backed.

First, there’s no good way to iterate over all the keys within memcached and doing so is problematic beyound the impelmentation more details can be found here => lists.danga.com/pipermail/memcached/2007-February/003610.html

Okay, so now what? Well we still have options:

- We could try Tugela Cache => http://meta.wikimedia.org/wiki/Tugela_Cache
- This looks promising => http://www.marcworrell.com/article-500-en.htmlhttp://www.marcworrell.com/article-500-en.html
- We could also store the keys in the ruby process or alternatively look in INVALIDATION-WITH-MEMCACHED

We can’t support advanced selector with memcached backend

Configuring:

config.cache do|c|
  c.memcached do|mc|
    mc.servers = ['localhost:11211']
    mc.debug = false
    mc.namespace = 'mesi'
    mc.readonly = false
  end
  c.ttl = 600
end

Instance Method Summary collapse

Methods included from Log

#log, #log_debug, #log_error, #log_request, #msg

Constructor Details

#initialize(options) ⇒ MemcachedCache

Returns a new instance of MemcachedCache.



103
104
105
106
107
108
109
110
111
# File 'lib/esi/cache.rb', line 103

def initialize( options )
  super()
  options = options.marshal_dump
  options.merge!( :multithread => true )
  puts "Using memcache with options => #{options.inspect}"
  @cache = MemCache.new options
  puts "Using memcache servers at #{options[:servers].inspect}"
  @cache.servers = options[:servers]
end

Instance Method Details

#cached?(uri, params) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
116
117
118
119
# File 'lib/esi/cache.rb', line 113

def cached?( uri, params )
  fragment = get(uri,params)
  fragment and fragment.valid?
rescue Object => e # never raise an exception from this method
  STDERR.puts "error in #{__FILE__}:#{__LINE__}"
  false
end

#delete(key) ⇒ Object



145
146
147
# File 'lib/esi/cache.rb', line 145

def delete( key )
  delete_unlocked
end

#delete_unlocked(key) ⇒ Object



149
150
151
# File 'lib/esi/cache.rb', line 149

def delete_unlocked( key )
  @cache.delete(key)
end

#get(uri, params) ⇒ Object



121
122
123
124
# File 'lib/esi/cache.rb', line 121

def get( uri, params )
  fragment = @cache.get(cache_key(uri,params))
  fragment.dup if fragment and fragment.respond_to?(:dup)
end

#keys(&block) ⇒ Object



140
141
142
143
# File 'lib/esi/cache.rb', line 140

def keys(&block)
  # TODO: can't implement this method directly with memcached, unless we introduce another key
  # and increase the data, but it is possible...
end

#put(uri, params, max_age, body) ⇒ Object



126
127
128
129
130
131
132
133
# File 'lib/esi/cache.rb', line 126

def put( uri, params, max_age, body )
  fragment = Fragment.new(uri,max_age,body)
  key = cache_key(uri,params)
  @cache.add( key, fragment, fragment.max_age )
rescue Object => e
  STDERR.puts "error in #{__FILE__}:#{__LINE__}"
			log_error e.message
end

#sweep!Object

run through the cache and dump anything that has expired



136
137
138
# File 'lib/esi/cache.rb', line 136

def sweep!
    # TODO: not really a memcached equivalent??
end

#sweep_unlocked!Object



153
154
# File 'lib/esi/cache.rb', line 153

def sweep_unlocked!
end