HEX
Server: Apache
System: Linux vpshost0650.publiccloud.com.br 4.4.79-grsec-1.lc.x86_64 #1 SMP Wed Aug 2 14:18:21 -03 2017 x86_64
User: bandeirantesbomb3 (10068)
PHP: 8.0.7
Disabled: apache_child_terminate,dl,escapeshellarg,escapeshellcmd,exec,link,mail,openlog,passthru,pcntl_alarm,pcntl_exec,pcntl_fork,pcntl_get_last_error,pcntl_getpriority,pcntl_setpriority,pcntl_signal,pcntl_signal_dispatch,pcntl_sigprocmask,pcntl_sigtimedwait,pcntl_sigwaitinfo,pcntl_strerror,pcntl_wait,pcntl_waitpid,pcntl_wexitstatus,pcntl_wifexited,pcntl_wifsignaled,pcntl_wifstopped,pcntl_wstopsig,pcntl_wtermsig,php_check_syntax,php_strip_whitespace,popen,proc_close,proc_open,shell_exec,symlink,system
Upload Files
File: //proc/thread-self/root/opt/puppetlabs/puppet/lib/ruby/vendor_ruby/mcollective/cache.rb
module MCollective
  # 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
  #
  module Cache
    # protects access to @cache_locks and top level @cache
    @locks_mutex = Mutex.new

    # stores a mutex per named cache
    @cache_locks = {}

    # the named caches protected by items in @cache_locks
    @cache = {}

    def self.setup(cache_name, ttl=300)
      @locks_mutex.synchronize do
        break if @cache_locks.include?(cache_name)

        @cache_locks[cache_name] = Mutex.new

        @cache_locks[cache_name].synchronize do
          @cache[cache_name] = {:max_age => Float(ttl)}
        end
      end

      true
    end

    def self.has_cache?(cache_name)
      @locks_mutex.synchronize do
        @cache.include?(cache_name)
      end
    end

    def self.delete!(cache_name)
      @locks_mutex.synchronize do
        raise("No cache called '%s'" % cache_name) unless @cache_locks.include?(cache_name)

        @cache_locks.delete(cache_name)
        @cache.delete(cache_name)
      end

      true
    end

    def self.write(cache_name, key, value)
      raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)

      @cache_locks[cache_name].synchronize do
        @cache[cache_name][key] ||= {}
        @cache[cache_name][key][:cache_create_time] = Time.now
        @cache[cache_name][key][:value] = value
      end

      value
    end

    def self.read(cache_name, key)
      raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)

      unless ttl(cache_name, key) > 0
        Log.debug("Cache expired on '%s' key '%s'" % [cache_name, key])
        raise("Cache for item '%s' on cache '%s' has expired" % [key, cache_name])
      end

      Log.debug("Cache hit on '%s' key '%s'" % [cache_name, key])

      @cache_locks[cache_name].synchronize do
        @cache[cache_name][key][:value]
      end
    end

    def self.ttl(cache_name, key)
      raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)

      @cache_locks[cache_name].synchronize do
        unless @cache[cache_name].include?(key)
          Log.debug("Cache miss on '%s' key '%s'" % [cache_name, key])
          raise("No item called '%s' for cache '%s'" % [key, cache_name])
        end

        @cache[cache_name][:max_age] - (Time.now - @cache[cache_name][key][:cache_create_time])
      end
    end

    def self.synchronize(cache_name)
      raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)

      raise ("No block supplied to synchronize") unless block_given?

      @cache_locks[cache_name].synchronize do
        yield
      end
    end

    def self.invalidate!(cache_name, key)
      raise("No cache called '%s'" % cache_name) unless @cache.include?(cache_name)

      @cache_locks[cache_name].synchronize do
        return false unless @cache[cache_name].include?(key)

        @cache[cache_name].delete(key)
      end
    end
  end
end