class Dalli::KeyManager
This class manages and validates keys sent to Memcached, ensuring that they meet Memcached key length requirements, and supporting the implementation of optional namespaces on a per-Dalli client basis.
Constants
- DEFAULTS
- MAX_KEY_LENGTH
- NAMESPACE_SEPARATOR
- OPTIONS
- TRUNCATED_KEY_SEPARATOR
-
This is a hard coded md5 for historical reasons
- TRUNCATED_KEY_TARGET_SIZE
-
This is 249 for historical reasons
Attributes
Public Class Methods
Source
# File lib/dalli/key_manager.rb, line 31 def initialize(client_options) @key_options = DEFAULTS.merge(client_options.select { |k, _| OPTIONS.include?(k) }) validate_digest_class_option(@key_options) @namespace = namespace_from_options end
Public Instance Methods
Source
# File lib/dalli/key_manager.rb, line 73 def digest_class @digest_class ||= @key_options[:digest_class] end
Source
# File lib/dalli/key_manager.rb, line 97 def evaluate_namespace return namespace.call.to_s if namespace.is_a?(Proc) namespace end
Source
# File lib/dalli/key_manager.rb, line 61 def key_with_namespace(key) return key if namespace.nil? "#{evaluate_namespace}#{NAMESPACE_SEPARATOR}#{key}" end
Returns the key with the namespace prefixed, if a namespace is defined. Otherwise just returns the key
Source
# File lib/dalli/key_manager.rb, line 67 def key_without_namespace(key) return key if namespace.nil? key.sub(namespace_regexp, '') end
Source
# File lib/dalli/key_manager.rb, line 89 def namespace_from_options raw_namespace = @key_options[:namespace] return nil unless raw_namespace return raw_namespace.to_s unless raw_namespace.is_a?(Proc) raw_namespace end
Source
# File lib/dalli/key_manager.rb, line 77 def namespace_regexp return /\A#{Regexp.escape(evaluate_namespace)}:/ if namespace.is_a?(Proc) @namespace_regexp ||= /\A#{Regexp.escape(namespace)}:/.freeze unless namespace.nil? end
Source
# File lib/dalli/key_manager.rb, line 113 def prefix_length(digest) return TRUNCATED_KEY_TARGET_SIZE - (TRUNCATED_KEY_SEPARATOR.length + digest.length) if namespace.nil? # For historical reasons, truncated keys with namespaces had a length of 250 rather # than 249 TRUNCATED_KEY_TARGET_SIZE + 1 - (TRUNCATED_KEY_SEPARATOR.length + digest.length) end
Source
# File lib/dalli/key_manager.rb, line 108 def truncated_key(key) digest = digest_class.hexdigest(key) "#{key[0, prefix_length(digest)]}#{TRUNCATED_KEY_SEPARATOR}#{digest}" end
Produces a truncated key, if the raw key is longer than the maximum allowed length. The truncated key is produced by generating a hex digest of the key, and appending that to a truncated section of the key.
Source
# File lib/dalli/key_manager.rb, line 83 def validate_digest_class_option(opts) return if opts[:digest_class].respond_to?(:hexdigest) raise ArgumentError, 'The digest_class object must respond to the hexdigest method' end
Source
# File lib/dalli/key_manager.rb, line 50 def validate_key(key) raise ArgumentError, 'key cannot be blank' unless key&.length&.positive? key = key_with_namespace(key) key.length > MAX_KEY_LENGTH ? truncated_key(key) : key end
Validates the key, and transforms as needed.
If the key is nil or empty, raises ArgumentError. Whitespace characters are allowed for historical reasons, but likely shouldn’t be used. If the key (with namespace) is shorter than the memcached maximum allowed key length, just returns the argument key Otherwise computes a “truncated” key that uses a truncated prefix combined with a 32-byte hex digest of the whole key.