lib/sfn/cache.rb in sfn-3.0.28 vs lib/sfn/cache.rb in sfn-3.0.30

- old
+ new

@@ -3,18 +3,17 @@ require 'sfn' module Sfn # Data caching helper class Cache - class << self # Configure the caching approach to use # # @param type [Symbol] :redis or :local # @param args [Hash] redis connection arguments if used - def configure(type, args={}) + def configure(type, args = {}) type = type.to_sym case type when :redis begin require 'redis-objects' @@ -47,13 +46,13 @@ # Set/get time limit on data type # # @param kind [String, Symbol] data type # @param seconds [Integer] # return [Integer] seconds - def apply_limit(kind, seconds=nil) + def apply_limit(kind, seconds = nil) @apply_limit ||= {} - if(seconds) + if seconds @apply_limit[kind.to_sym] = seconds.to_i end @apply_limit[kind.to_sym].to_i end @@ -62,26 +61,25 @@ (@apply_limit || {}).dup end # Ping the redis connection and reconnect if dead def redis_ping! - if((@_pid && @_pid != Process.pid) || !Redis::Objects.redis.connected?) + if (@_pid && @_pid != Process.pid) || !Redis::Objects.redis.connected? Redis::Objects.redis.client.reconnect @_pid = Process.pid end end - end # @return [String] custom key for this cache attr_reader :key # Create new instance # # @param key [String, Array] def initialize(key) - if(key.respond_to?(:sort)) + if key.respond_to?(:sort) key = key.flatten if key.respond_to?(:flatten) key = key.map(&:to_s).sort end @key = Digest::SHA256.hexdigest(key.to_s) @apply_limit = self.class.default_limits @@ -90,11 +88,11 @@ # Initialize a new data type # # @param name [Symbol] name of data # @param kind [Symbol] data type # @param args [Hash] options for data type - def init(name, kind, args={}) + def init(name, kind, args = {}) get_storage(self.class.type, kind, name, args) true end # @return [Hash] data registry @@ -110,13 +108,13 @@ def clear!(*args) internal_lock do args = registry.keys if args.empty? args.each do |key| value = self[key] - if(value.respond_to?(:clear)) + if value.respond_to?(:clear) value.clear - elsif(value.respond_to?(:value)) + elsif value.respond_to?(:value) value.value = nil end registry.delete(key) end yield if block_given? @@ -129,26 +127,26 @@ # @param store_type [Symbol] # @param data_type [Symbol] # @param name [Symbol] name of data # @param args [Hash] options for underlying storage # @return [Object] - def get_storage(store_type, data_type, name, args={}) + def get_storage(store_type, data_type, name, args = {}) full_name = "#{key}_#{name}" result = nil case store_type.to_sym when :redis result = get_redis_storage(data_type, full_name.to_s, args) when :local @_local_cache ||= {} - unless(@_local_cache[full_name.to_s]) + unless @_local_cache[full_name.to_s] @_local_cache[full_name.to_s] = get_local_storage(data_type, full_name.to_s, args) end result = @_local_cache[full_name.to_s] else raise TypeError.new("Unsupported caching storage type encountered: #{store_type}") end - unless(full_name == "#{key}_registry_#{key}") + unless full_name == "#{key}_registry_#{key}" registry[name.to_s] = data_type end result end @@ -156,11 +154,11 @@ # # @param data_type [Symbol] # @param full_name [Symbol] # @param args [Hash] # @return [Object] - def get_redis_storage(data_type, full_name, args={}) + def get_redis_storage(data_type, full_name, args = {}) self.class.redis_ping! case data_type.to_sym when :array Redis::List.new(full_name, {:marshal => true}.merge(args)) when :hash @@ -181,26 +179,26 @@ # @param data_type [Symbol] # @param full_name [Symbol] # @param args [Hash] # @return [Object] # @todo make proper singleton for local storage - def get_local_storage(data_type, full_name, args={}) + def get_local_storage(data_type, full_name, args = {}) @storage ||= {} @storage[full_name] ||= case data_type.to_sym - when :array - [] - when :hash - {} - when :value - LocalValue.new - when :lock - LocalLock.new(full_name, {:expiration => 60, :timeout => 0.1}.merge(args)) - when :stamped - Stamped.new(full_name.sub("#{key}_", '').to_sym, get_local_storage(:value, full_name), self) - else - raise TypeError.new("Unsupported caching data type encountered: #{data_type}") - end + when :array + [] + when :hash + {} + when :value + LocalValue.new + when :lock + LocalLock.new(full_name, {:expiration => 60, :timeout => 0.1}.merge(args)) + when :stamped + Stamped.new(full_name.sub("#{key}_", '').to_sym, get_local_storage(:value, full_name), self) + else + raise TypeError.new("Unsupported caching data type encountered: #{data_type}") + end end # Execute block within internal lock # # @return [Object] result of yield @@ -214,11 +212,11 @@ # Fetch data # # @param name [String, Symbol] # @return [Object, NilClass] def [](name) - if(kind = registry[name.to_s]) + if kind = registry[name.to_s] get_storage(self.class.type, kind, name) else nil end end @@ -244,30 +242,30 @@ # Apply time limit for data type # # @param kind [String, Symbol] data type # @param seconds [Integer] # return [Integer] - def apply_limit(kind, seconds=nil) + def apply_limit(kind, seconds = nil) @apply_limit ||= {} - if(seconds) + if seconds @apply_limit[kind.to_sym] = seconds.to_i end @apply_limit[kind.to_sym].to_i end # Perform action within lock # # @param lock_name [String, Symbol] name of lock # @param raise_on_locked [TrueClass, FalseClass] raise execption if lock wait times out # @return [Object] result of yield - def locked_action(lock_name, raise_on_locked=false) + def locked_action(lock_name, raise_on_locked = false) begin self[lock_name].lock do yield end rescue => e - if(e.class.to_s.end_with?('Timeout')) + if e.class.to_s.end_with?('Timeout') raise if raise_on_locked else raise end end @@ -275,18 +273,18 @@ # Simple value for memory cache class LocalValue # @return [Object] value attr_accessor :value + def initialize(*args) @value = nil end end # Simple lock for memory cache class LocalLock - class LocalLockTimeout < RuntimeError end # @return [Symbol] key name attr_reader :_key @@ -298,11 +296,11 @@ # Create new instance # # @param name [Symbol] name of lock # @param args [Hash] # @option args [Numeric] :timeout - def initialize(name, args={}) + def initialize(name, args = {}) @_key = name @_timeout = args.fetch(:timeout, -1).to_f @_lock = Mutex.new end @@ -311,21 +309,21 @@ # @yield block to execute within lock # @return [Object] result of yield def lock locked = false attempt_start = Time.now.to_f - while(!locked && (_timeout < 0 || Time.now.to_f - attempt_start < _timeout)) + while (!locked && (_timeout < 0 || Time.now.to_f - attempt_start < _timeout)) locked = _lock.try_lock end - if(locked) + if locked begin yield ensure _lock.unlock if _lock.locked? end else - if(defined?(Redis)) + if defined?(Redis) raise Redis::Lock::LockTimeout.new "Timeout on lock #{_key} exceeded #{_timeout} sec" else raise LocalLockTimeout.new "Timeout on lock #{_key} exceeded #{_timeout} sec" end end @@ -385,8 +383,7 @@ # @return [TrueClass, FalseClass] update is allowed based on stamp and limits def update_allowed? !set? || @cache.time_check_allow?(@name, @base.value[:stamp]) end end - end end