module MCollective::Cache - mcollective version 2.12.5

# module MCollective::Cache

A class to manage a number of named caches. Each cache can have a unique timeout for keys in it and each cache has an independent Mutex protecting access to it.

This cache is setup early in the process of loading the mcollective libraries, before any threads are created etc making it suitable as a cross thread cache or just a store for Mutexes you need to use across threads like in an `Agent` or something.

    # sets up a new cache, noop if it already exist
    Cache.setup(:ddl, 600)
    => true

    # writes an item to the :ddl cache, this item will
    # be valid on the cache for 600 seconds
    Cache.write(:ddl, :something, "value")
    => "value"

    # reads from the cache, read failures due to non existing
    # data or expired data will raise an exception
    Cache.read(:ddl, :something)
    => "value"

    # time left till expiry, raises if nothing is found
    Cache.ttl(:ddl, :something)
    => 500

    # forcibly evict something from the cache
    Cache.invalidate!(:ddl, :something)
    => "value"

    # deletes an entire named cache and its mutexes
    Cache.delete!(:ddl)
    => true

    # you can also just use this cache as a global mutex store
    Cache.setup(:mylock)

    Cache.synchronize(:mylock) do
      do_something()
    end

### Public Class Methods

delete!(cache_name) click to toggle source

       # File lib/mcollective/cache.rb
    74 def self.delete!(cache_name)
    75   @locks_mutex.synchronize do
    76     raise("No cache called '%s'" % cache_name) unless @cache_locks.include?(cache_name)
    77
    78     @cache_locks.delete(cache_name)
    79     @cache.delete(cache_name)
    80   end
    81
    82   true
    83 end

has_cache?(cache_name) click to toggle source

       # File lib/mcollective/cache.rb
    68 def self.has_cache?(cache_name)
    69   @locks_mutex.synchronize do
    70     @cache.include?(cache_name)
    71   end
    72 end

invalidate!(cache_name, key) click to toggle source

        # File lib/mcollective/cache.rb
    135 def self.invalidate!(cache_name, key)
    136   raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)
    137
    138   @cache_locks[cache_name].synchronize do
    139     return false unless @cache[cache_name].include?(key)
    140
    141     @cache[cache_name].delete(key)
    142   end
    143 end

read(cache_name, key) click to toggle source

        # File lib/mcollective/cache.rb
     97 def self.read(cache_name, key)
     98   raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)
     99
    100   unless ttl(cache_name, key) > 0
    101     Log.debug("Cache expired on '%s' key '%s'" % [cache_name, key])
    102     raise("Cache for item '%s' on cache '%s' has expired" % [key, cache_name])
    103   end
    104
    105   Log.debug("Cache hit on '%s' key '%s'" % [cache_name, key])
    106
    107   @cache_locks[cache_name].synchronize do
    108     @cache[cache_name][key][:value]
    109   end
    110 end

setup(cache_name, ttl=300) click to toggle source

       # File lib/mcollective/cache.rb
    54 def self.setup(cache_name, ttl=300)
    55   @locks_mutex.synchronize do
    56     break if @cache_locks.include?(cache_name)
    57
    58     @cache_locks[cache_name] = Mutex.new
    59
    60     @cache_locks[cache_name].synchronize do
    61       @cache[cache_name] = {:max_age => Float(ttl)}
    62     end
    63   end
    64
    65   true
    66 end

synchronize(cache_name) { || ... } click to toggle source

        # File lib/mcollective/cache.rb
    125 def self.synchronize(cache_name)
    126   raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)
    127
    128   raise ("No block supplied to synchronize") unless block_given?
    129
    130   @cache_locks[cache_name].synchronize do
    131     yield
    132   end
    133 end

ttl(cache_name, key) click to toggle source

        # File lib/mcollective/cache.rb
    112 def self.ttl(cache_name, key)
    113   raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)
    114
    115   @cache_locks[cache_name].synchronize do
    116     unless @cache[cache_name].include?(key)
    117       Log.debug("Cache miss on '%s' key '%s'" % [cache_name, key])
    118       raise("No item called '%s' for cache '%s'" % [key, cache_name])
    119     end
    120
    121     @cache[cache_name][:max_age] - (Time.now - @cache[cache_name][key][:cache_create_time])
    122   end
    123 end

write(cache_name, key, value) click to toggle source

       # File lib/mcollective/cache.rb
    85 def self.write(cache_name, key, value)
    86   raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)
    87
    88   @cache_locks[cache_name].synchronize do
    89     @cache[cache_name][key] ||= {}
    90     @cache[cache_name][key][:cache_create_time] = Time.now
    91     @cache[cache_name][key][:value] = value
    92   end
    93
    94   value
    95 end