Extract Cache::Entry into a separate file
`activesupport/lib/active_support/cache.rb` is already rather long, and having a separate file allows subclasses of `Cache::Entry` to be defined without first requiring `activesupport/lib/active_support/cache.rb`.
This commit is contained in:
parent
ef703fecac
commit
c7a23018f5
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "zlib"
|
||||
require "active_support/core_ext/array/extract_options"
|
||||
require "active_support/core_ext/enumerable"
|
||||
require "active_support/core_ext/module/attribute_accessors"
|
||||
@ -8,6 +7,7 @@
|
||||
require "active_support/core_ext/object/to_param"
|
||||
require "active_support/core_ext/object/try"
|
||||
require "active_support/core_ext/string/inflections"
|
||||
require_relative "cache/entry"
|
||||
require_relative "cache/serializer_with_fallback"
|
||||
|
||||
module ActiveSupport
|
||||
@ -986,126 +986,5 @@ def expires_at=(expires_at)
|
||||
@options[:expires_at] = expires_at
|
||||
end
|
||||
end
|
||||
|
||||
# This class is used to represent cache entries. Cache entries have a value, an optional
|
||||
# expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option
|
||||
# on the cache. The version is used to support the :version option on the cache for rejecting
|
||||
# mismatches.
|
||||
#
|
||||
# Since cache entries in most instances will be serialized, the internals of this class are highly optimized
|
||||
# using short instance variable names that are lazily defined.
|
||||
class Entry # :nodoc:
|
||||
class << self
|
||||
def unpack(members)
|
||||
new(members[0], expires_at: members[1], version: members[2])
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :version
|
||||
|
||||
# Creates a new cache entry for the specified value. Options supported are
|
||||
# +:compressed+, +:version+, +:expires_at+ and +:expires_in+.
|
||||
def initialize(value, compressed: false, version: nil, expires_in: nil, expires_at: nil, **)
|
||||
@value = value
|
||||
@version = version
|
||||
@created_at = 0.0
|
||||
@expires_in = expires_at&.to_f || expires_in && (expires_in.to_f + Time.now.to_f)
|
||||
@compressed = true if compressed
|
||||
end
|
||||
|
||||
def value
|
||||
compressed? ? uncompress(@value) : @value
|
||||
end
|
||||
|
||||
def mismatched?(version)
|
||||
@version && version && @version != version
|
||||
end
|
||||
|
||||
# Checks if the entry is expired. The +expires_in+ parameter can override
|
||||
# the value set when the entry was created.
|
||||
def expired?
|
||||
@expires_in && @created_at + @expires_in <= Time.now.to_f
|
||||
end
|
||||
|
||||
def expires_at
|
||||
@expires_in ? @created_at + @expires_in : nil
|
||||
end
|
||||
|
||||
def expires_at=(value)
|
||||
if value
|
||||
@expires_in = value.to_f - @created_at
|
||||
else
|
||||
@expires_in = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the size of the cached value. This could be less than
|
||||
# <tt>value.bytesize</tt> if the data is compressed.
|
||||
def bytesize
|
||||
case value
|
||||
when NilClass
|
||||
0
|
||||
when String
|
||||
@value.bytesize
|
||||
else
|
||||
@s ||= Marshal.dump(@value).bytesize
|
||||
end
|
||||
end
|
||||
|
||||
def compressed? # :nodoc:
|
||||
defined?(@compressed)
|
||||
end
|
||||
|
||||
def compressed(compress_threshold)
|
||||
return self if compressed?
|
||||
|
||||
case @value
|
||||
when nil, true, false, Numeric
|
||||
uncompressed_size = 0
|
||||
when String
|
||||
uncompressed_size = @value.bytesize
|
||||
else
|
||||
serialized = Marshal.dump(@value)
|
||||
uncompressed_size = serialized.bytesize
|
||||
end
|
||||
|
||||
if uncompressed_size >= compress_threshold
|
||||
serialized ||= Marshal.dump(@value)
|
||||
compressed = Zlib::Deflate.deflate(serialized)
|
||||
|
||||
if compressed.bytesize < uncompressed_size
|
||||
return Entry.new(compressed, compressed: true, expires_at: expires_at, version: version)
|
||||
end
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def local?
|
||||
false
|
||||
end
|
||||
|
||||
# Duplicates the value in a class. This is used by cache implementations that don't natively
|
||||
# serialize entries to protect against accidental cache modifications.
|
||||
def dup_value!
|
||||
if @value && !compressed? && !(@value.is_a?(Numeric) || @value == true || @value == false)
|
||||
if @value.is_a?(String)
|
||||
@value = @value.dup
|
||||
else
|
||||
@value = Marshal.load(Marshal.dump(@value))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pack
|
||||
members = [value, expires_at, version]
|
||||
members.pop while !members.empty? && members.last.nil?
|
||||
members
|
||||
end
|
||||
|
||||
private
|
||||
def uncompress(value)
|
||||
Marshal.load(Zlib::Inflate.inflate(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
128
activesupport/lib/active_support/cache/entry.rb
vendored
Normal file
128
activesupport/lib/active_support/cache/entry.rb
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "zlib"
|
||||
|
||||
module ActiveSupport
|
||||
module Cache
|
||||
# This class is used to represent cache entries. Cache entries have a value, an optional
|
||||
# expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option
|
||||
# on the cache. The version is used to support the :version option on the cache for rejecting
|
||||
# mismatches.
|
||||
#
|
||||
# Since cache entries in most instances will be serialized, the internals of this class are highly optimized
|
||||
# using short instance variable names that are lazily defined.
|
||||
class Entry # :nodoc:
|
||||
class << self
|
||||
def unpack(members)
|
||||
new(members[0], expires_at: members[1], version: members[2])
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :version
|
||||
|
||||
# Creates a new cache entry for the specified value. Options supported are
|
||||
# +:compressed+, +:version+, +:expires_at+ and +:expires_in+.
|
||||
def initialize(value, compressed: false, version: nil, expires_in: nil, expires_at: nil, **)
|
||||
@value = value
|
||||
@version = version
|
||||
@created_at = 0.0
|
||||
@expires_in = expires_at&.to_f || expires_in && (expires_in.to_f + Time.now.to_f)
|
||||
@compressed = true if compressed
|
||||
end
|
||||
|
||||
def value
|
||||
compressed? ? uncompress(@value) : @value
|
||||
end
|
||||
|
||||
def mismatched?(version)
|
||||
@version && version && @version != version
|
||||
end
|
||||
|
||||
# Checks if the entry is expired. The +expires_in+ parameter can override
|
||||
# the value set when the entry was created.
|
||||
def expired?
|
||||
@expires_in && @created_at + @expires_in <= Time.now.to_f
|
||||
end
|
||||
|
||||
def expires_at
|
||||
@expires_in ? @created_at + @expires_in : nil
|
||||
end
|
||||
|
||||
def expires_at=(value)
|
||||
if value
|
||||
@expires_in = value.to_f - @created_at
|
||||
else
|
||||
@expires_in = nil
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the size of the cached value. This could be less than
|
||||
# <tt>value.bytesize</tt> if the data is compressed.
|
||||
def bytesize
|
||||
case value
|
||||
when NilClass
|
||||
0
|
||||
when String
|
||||
@value.bytesize
|
||||
else
|
||||
@s ||= Marshal.dump(@value).bytesize
|
||||
end
|
||||
end
|
||||
|
||||
def compressed? # :nodoc:
|
||||
defined?(@compressed)
|
||||
end
|
||||
|
||||
def compressed(compress_threshold)
|
||||
return self if compressed?
|
||||
|
||||
case @value
|
||||
when nil, true, false, Numeric
|
||||
uncompressed_size = 0
|
||||
when String
|
||||
uncompressed_size = @value.bytesize
|
||||
else
|
||||
serialized = Marshal.dump(@value)
|
||||
uncompressed_size = serialized.bytesize
|
||||
end
|
||||
|
||||
if uncompressed_size >= compress_threshold
|
||||
serialized ||= Marshal.dump(@value)
|
||||
compressed = Zlib::Deflate.deflate(serialized)
|
||||
|
||||
if compressed.bytesize < uncompressed_size
|
||||
return Entry.new(compressed, compressed: true, expires_at: expires_at, version: version)
|
||||
end
|
||||
end
|
||||
self
|
||||
end
|
||||
|
||||
def local?
|
||||
false
|
||||
end
|
||||
|
||||
# Duplicates the value in a class. This is used by cache implementations that don't natively
|
||||
# serialize entries to protect against accidental cache modifications.
|
||||
def dup_value!
|
||||
if @value && !compressed? && !(@value.is_a?(Numeric) || @value == true || @value == false)
|
||||
if @value.is_a?(String)
|
||||
@value = @value.dup
|
||||
else
|
||||
@value = Marshal.load(Marshal.dump(@value))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pack
|
||||
members = [value, expires_at, version]
|
||||
members.pop while !members.empty? && members.last.nil?
|
||||
members
|
||||
end
|
||||
|
||||
private
|
||||
def uncompress(value)
|
||||
Marshal.load(Zlib::Inflate.inflate(value))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1,5 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "zlib"
|
||||
require "active_support/core_ext/kernel/reporting"
|
||||
|
||||
module ActiveSupport
|
||||
|
Loading…
Reference in New Issue
Block a user