### Home Classes Methods

### In Files

- lib/memcache.rb
- lib/memcache/local_server.rb
- lib/memcache/segmented.rb
- lib/memcache/base.rb
- lib/memcache/migration.rb
- lib/memcache/server.rb
- lib/memcache/null_server.rb
- lib/memcache/pg_server.rb

### Parent

Object

### Namespace

- MODULE Memcache::Segmented
- CLASS Memcache::Base
- CLASS Memcache::ClientError
- CLASS Memcache::ConnectionError
- CLASS Memcache::Error
- CLASS Memcache::LocalServer
- CLASS Memcache::Migration
- CLASS Memcache::NullServer
- CLASS Memcache::PGServer
- CLASS Memcache::Pool
- CLASS Memcache::SegmentedNativeServer
- CLASS Memcache::SegmentedServer
- CLASS Memcache::Server
- CLASS Memcache::ServerError

### Methods

- ::init
- ::new
- ::pool
- #[]
- #[]=
- #add
- #add_or_get
- #append
- #cas
- #clear
- #clone
- #compatible_opts
- #count
- #decr
- #delete
- #flush_all
- #get
- #get_or_add
- #get_or_set
- #get_some
- #in_namespace
- #incr
- #inspect
- #lock
- #lock_key
- #locked?
- #marshal
- #multi_get
- #namespace=
- #prepend
- #read
- #read_multi
- #replace
- #reset
- #server
- #set
- #stats
- #unlock
- #unmarshal
- #update
- #with_lock
- #write

### Class/Module Index

Quicksearch

- Memcache
- Memcache::Base
- Memcache::ClientError
- Memcache::ConnectionError
- Memcache::Error
- Memcache::LocalServer
- Memcache::Migration
- Memcache::NullServer
- Memcache::PGServer
- Memcache::Pool
- Memcache::Segmented
- Memcache::SegmentedNativeServer
- Memcache::SegmentedServer
- Memcache::Server
- Memcache::ServerError
- Object
- PGconn

No matching classes.

# Memcache

### Constants

DEFAULT_EXPIRY
LOCK_TIMEOUT
WRITE_LOCK_WAIT

### Attributes

backup[R]
default_expiry[R]
namespace[R]
servers[R]

### Public Class Methods

init(yaml_file = nil) click to toggle source

    # File lib/memcache.rb, line 352
    def self.init(yaml_file = nil)
      yaml_file ||= File.join(Rails.root, 'config', 'memcached.yml')

      if File.exists?(yaml_file)
        yaml = YAML.load_file(yaml_file)
        defaults = (yaml.delete('defaults') || {}).symbolize_keys
        config   = (yaml[Rails.env] || {}).symbolize_keys

        if not config.empty? and not config[:disabled]
          if config[:servers]
            opts = defaults.merge(config.symbolize_keys)
            Object.const_set('CACHE', Memcache.new(opts))
          else
            config.each do |connection, opts|
              opts = defaults.merge(opts.symbolize_keys)
              if not opts.empty? and not opts[:disabled]
                Memcache.pool[connection] = Memcache.new(opts)
              end
            end
          end
        end
      end
    end

new(opts) click to toggle source

    # File lib/memcache.rb, line 35
    def initialize(opts)
      @default_expiry   = opts[:default_expiry] || DEFAULT_EXPIRY
      @backup           = opts[:backup] # for multi-level caches
      @hash_with_prefix = opts[:hash_with_prefix].nil? ? true : opts[:hash_with_prefix]

      if opts[:native]
        native_opts = opts.clone
        native_opts[:servers] = (opts[:servers] || [ opts[:server] ]).collect do |server|
          server.is_a?(Hash) ? "#{server[:host]}:#{server[:port]}:#{server[:weight]}" : server
        end
        native_opts[:hash] ||= :crc unless native_opts[:ketama] or native_opts[:ketama_wieghted]
        native_opts[:hash_with_prefix] = @hash_with_prefix

        server_class = opts[:segment_large_values] ? SegmentedNativeServer : NativeServer
        @servers = [server_class.new(native_opts)]
      else
        raise "only CRC hashing is supported unless :native => true" if opts[:hash] and opts[:hash] != :crc

        server_class = opts[:segment_large_values] ? SegmentedServer : Server
        @servers = (opts[:servers] || [ opts[:server] ]).collect do |server|
          case server
          when Hash
            server = server_class.new(opts.merge(server))
          when String
            host, port = server.split(':')
            server = server_class.new(opts.merge(:host => host, :port => port))
          when Class
            server = server.new
          when :local
            server = Memcache::LocalServer.new
          end
          server
        end
      end

      @server = @servers.first if @servers.size == 1 and @backup.nil?
      self.namespace = opts[:namespace] if opts[:namespace]
    end

### Protected Class Methods

pool() click to toggle source

    # File lib/memcache.rb, line 471
    def self.pool
      @@cache_pool ||= Pool.new
    end

### Public Instance Methods

[](key) click to toggle source

    # File lib/memcache.rb, line 344
    def [](key)
      get(key)
    end

[]=(key, value) click to toggle source

    # File lib/memcache.rb, line 348
    def []=(key, value)
      set(key, value)
    end

add(key, value, opts = {}) click to toggle source

    # File lib/memcache.rb, line 153
    def add(key, value, opts = {})
      opts = compatible_opts(opts)
      key  = key.to_s
      backup.add(key, value, opts) if backup

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

add_or_get(key, value, opts = {}) click to toggle source

    # File lib/memcache.rb, line 252
    def add_or_get(key, value, opts = {})
      # Try to add, but if that fails, get the existing value.
      add(key, value, opts) || get(key)
    end

append(key, value) click to toggle source

    # File lib/memcache.rb, line 186
    def append(key, value)
      key = key.to_s
      backup.append(key, value) if backup
      server(key).append(key, value)
    end

cas(key, value, opts) click to toggle source

    # File lib/memcache.rb, line 175
    def cas(key, value, opts)
      raise 'opts must be hash' unless opts.instance_of?(Hash)
      key = key.to_s
      backup.cas(key, value, opts) if backup

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

clear(opts = {}) click to toggle source
Alias for: flush_all
clone() click to toggle source

    # File lib/memcache.rb, line 74
    def clone
      self.class.new(
        :default_expiry => default_expiry,
        :namespace      => namespace,
        :servers        => servers.collect {|s| s.clone}
      )
    end

count(key) click to toggle source

    # File lib/memcache.rb, line 198
    def count(key)
      value = get(key, :raw => true)
      value.to_i if value
    end

decr(key, amount = 1) click to toggle source

    # File lib/memcache.rb, line 211
    def decr(key, amount = 1)
      return incr(key, -amount) if amount < 0

      key = key.to_s
      backup.decr(key, amount) if backup
      server(key).decr(key, amount)
    end

delete(key) click to toggle source

    # File lib/memcache.rb, line 308
    def delete(key)
      key = key.to_s
      backup.delete(key) if backup
      server(key).delete(key)
    end

flush_all(opts = {}) click to toggle source

    # File lib/memcache.rb, line 314
    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

Also aliased as: clear
get(keys, opts = {}) click to toggle source

    # File lib/memcache.rb, line 107
    def get(keys, opts = {})
      raise 'opts must be hash' unless opts.instance_of?(Hash)

      if keys.instance_of?(Array)
        keys = keys.collect {|key| key.to_s}
        multi_get(keys, opts)
      else
        key = keys.to_s
        if opts[:expiry]
          value = server(key).gets(key)
          cas(key, value, :raw => true, :cas => value.memcache_cas, :expiry => opts[:expiry]) if value
        else
          value = server(key).get(key, opts[:cas])
        end

        return backup.get(key, opts) if backup and value.nil?
        opts[:raw] ? value : unmarshal(value, key)
      end
    end

get_or_add(key, *args) click to toggle source

    # File lib/memcache.rb, line 229
    def get_or_add(key, *args)
      # Pseudo-atomic get and update.
      key = key.to_s
      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) click to toggle source

    # File lib/memcache.rb, line 241
    def get_or_set(key, *args)
      key = key.to_s
      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 = {}) click to toggle source

    # File lib/memcache.rb, line 257
    def get_some(keys, opts = {})
      keys = keys.collect {|key| key.to_s}
      records = opts[:disable] ? {} : self.multi_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
      if keys_to_fetch.any?
        yield(keys_to_fetch).each do |key, value|
          begin
            set(key, value, {}) unless opts[:disable] or opts[:disable_write]
          rescue Memcache::Error => e
            raise if opts[:strict_write]
            $stderr.puts "Memcache error in get_some: #{e.class} #{e.to_s} on key '#{key}' while storing value: #{value}"
          end
          records[key] = value
        end
      end
      records
    end

in_namespace(namespace) click to toggle source

    # File lib/memcache.rb, line 96
    def in_namespace(namespace)
      # Temporarily change the namespace for convenience.
      begin
        old_namespace  = self.namespace
        self.namespace = old_namespace ? "#{old_namespace}:#{namespace}" : namespace
        yield
      ensure
        self.namespace = old_namespace
      end
    end

incr(key, amount = 1) click to toggle source

    # File lib/memcache.rb, line 203
    def incr(key, amount = 1)
      return decr(key, -amount) if amount < 0

      key = key.to_s
      backup.incr(key, amount) if backup
      server(key).incr(key, amount)
    end

inspect() click to toggle source

    # File lib/memcache.rb, line 82
    def inspect
      "<Memcache: %d servers, ns: %p>" % [@servers.length, namespace]
    end

lock(key, opts = {}) click to toggle source

    # File lib/memcache.rb, line 281
    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) click to toggle source

    # File lib/memcache.rb, line 300
    def lock_key(key)
      "lock:#{key}"
    end

locked?(key) click to toggle source

    # File lib/memcache.rb, line 304
    def locked?(key)
      get(lock_key(key), :raw => true)
    end

namespace=(namespace) click to toggle source

    # File lib/memcache.rb, line 86
    def namespace=(namespace)
      @namespace = namespace
      prefix = namespace ? "#{namespace}:" : nil
      servers.each do |server|
        server.prefix = prefix
      end
      backup.namespace = @namespace if backup
      @namespace
    end

prepend(key, value) click to toggle source

    # File lib/memcache.rb, line 192
    def prepend(key, value)
      key = key.to_s
      backup.prepend(key, value) if backup
      server(key).prepend(key, value)
    end

read(key, opts = nil) click to toggle source

    # File lib/memcache.rb, line 127
    def read(key, opts = nil)
      opts ||= {}
      get(key, opts.merge(:raw => true))
    end

read_multi(*keys) click to toggle source

    # File lib/memcache.rb, line 132
    def read_multi(*keys)
      get(keys)
    end

replace(key, value, opts = {}) click to toggle source

    # File lib/memcache.rb, line 164
    def replace(key, value, opts = {})
      opts = compatible_opts(opts)
      key  = key.to_s
      backup.replace(key, value, opts) if backup

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

reset() click to toggle source

    # File lib/memcache.rb, line 324
    def reset
      servers.each {|server| server.close if server.respond_to?(:close)}
    end

set(key, value, opts = {}) click to toggle source

    # File lib/memcache.rb, line 136
    def set(key, value, opts = {})
      opts = compatible_opts(opts)
      key  = key.to_s
      backup.set(key, value, opts) if backup

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

stats(field = nil) click to toggle source

    # File lib/memcache.rb, line 328
    def stats(field = nil)
      if field
        servers.collect do |server|
          server.stats[field]
        end
      else
        stats = {}
        servers.each do |server|
          stats[server.name] = server.stats
        end
        stats
      end
    end

unlock(key) click to toggle source

    # File lib/memcache.rb, line 287
    def unlock(key)
      delete(lock_key(key))
    end

update(key, opts = {}) click to toggle source

    # File lib/memcache.rb, line 219
    def update(key, opts = {})
      key   = key.to_s
      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 = {}) click to toggle source

    # File lib/memcache.rb, line 291
    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 = nil) click to toggle source

    # File lib/memcache.rb, line 148
    def write(key, value, opts = nil)
      opts ||= {}
      set(key, value, opts.merge(:raw => true))
    end

### Protected Instance Methods

compatible_opts(opts) click to toggle source

    # File lib/memcache.rb, line 378
    def compatible_opts(opts)
      # Support passing expiry instead of opts. This may be deprecated in the future.
      opts.instance_of?(Hash) ? opts : {:expiry => opts}
    end

marshal(value, opts = {}) click to toggle source

    # File lib/memcache.rb, line 416
    def marshal(value, opts = {})
      opts[:raw] ? value : Marshal.dump(value)
    end

multi_get(keys, opts = {}) click to toggle source

    # File lib/memcache.rb, line 383
    def multi_get(keys, opts = {})
      return {} if keys.empty?

      results = {}
      fetch_results = lambda do |server, keys|
        server.get(keys, opts[:cas]).each do |key, value|
          results[key] = opts[:raw] ? value : unmarshal(value, key)
        end
      end

      if @server
        fetch_results.call(@server, keys)
      else
        keys_by_server = Hash.new { |h,k| h[k] = [] }

        # Store keys by servers.
        keys.each do |key|
          keys_by_server[server(key)] << key
        end

        # Fetch and combine the results.
        keys_by_server.each do |server, server_keys|
          fetch_results.call(server, server_keys)
        end
      end

      if backup
        missing_keys = keys - results.keys
        results.merge!(backup.get(missing_keys, opts)) if missing_keys.any?
      end
      results
    end

server(key) click to toggle source

    # File lib/memcache.rb, line 433
    def server(key)
      return @server if @server

      key = "#{namespace}:#{key}" if @hash_with_prefix and namespace
      hash = (Zlib.crc32(key) >> 16) & 0x7fff
      servers[hash % servers.length]
    end

unmarshal(value, key = nil) click to toggle source

    # File lib/memcache.rb, line 420
    def unmarshal(value, key = nil)
      return value if value.nil?

      object = Marshal.load(value)
      object.memcache_flags = value.memcache_flags
      object.memcache_cas   = value.memcache_cas
      object
    rescue Exception => e
      $stderr.puts "Memcache read error: #{e.class} #{e.to_s} on key '#{key}' while unmarshalling value: #{value}"
      $stderr.puts caller
      nil
    end

[Validate]

Generated with the Darkfish Rdoc Generator 2.