activesupport 5.1.1 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +360 -442
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -4
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +6 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -3
- data/lib/active_support/benchmarkable.rb +3 -1
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +37 -36
- data/lib/active_support/cache/mem_cache_store.rb +65 -53
- data/lib/active_support/cache/memory_store.rb +61 -33
- data/lib/active_support/cache/null_store.rb +10 -3
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +68 -22
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +305 -127
- data/lib/active_support/callbacks.rb +106 -98
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -1
- data/lib/active_support/configurable.rb +12 -14
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +7 -5
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +3 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +18 -40
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -5
- data/lib/active_support/core_ext/date/conversions.rb +12 -10
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +174 -71
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -5
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +3 -30
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/marshal.rb +4 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +103 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +3 -1
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -1
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +13 -3
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +6 -101
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +22 -2
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +7 -2
- data/lib/active_support/core_ext/object/try.rb +19 -7
- data/lib/active_support/core_ext/object/with_options.rb +4 -2
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +3 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +3 -0
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +76 -20
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +73 -18
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +4 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +11 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +208 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +135 -60
- data/lib/active_support/deprecation/behaviors.rb +43 -11
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +30 -15
- data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +9 -2
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +6 -6
- data/lib/active_support/duration/iso8601_serializer.rb +20 -14
- data/lib/active_support/duration.rb +179 -41
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +84 -117
- data/lib/active_support/execution_wrapper.rb +3 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +134 -37
- data/lib/active_support/i18n.rb +4 -1
- data/lib/active_support/i18n_railtie.rb +20 -11
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +19 -8
- data/lib/active_support/inflector/methods.rb +87 -77
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +13 -3
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -33
- data/lib/active_support/lazy_load_hooks.rb +33 -10
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/log_subscriber.rb +46 -13
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +54 -7
- data/lib/active_support/message_encryptor.rb +101 -33
- data/lib/active_support/message_verifier.rb +85 -14
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +12 -68
- data/lib/active_support/multibyte/unicode.rb +17 -327
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +118 -16
- data/lib/active_support/notifications/instrumenter.rb +73 -9
- data/lib/active_support/notifications.rb +74 -8
- data/lib/active_support/number_helper/number_converter.rb +7 -6
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
- data/lib/active_support/number_helper/rounding_helper.rb +50 -0
- data/lib/active_support/number_helper.rb +41 -12
- data/lib/active_support/option_merger.rb +24 -3
- data/lib/active_support/ordered_hash.rb +3 -1
- data/lib/active_support/ordered_options.rb +17 -5
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +3 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +60 -9
- data/lib/active_support/reloader.rb +11 -10
- data/lib/active_support/rescuable.rb +7 -6
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +6 -3
- data/lib/active_support/subscriber.rb +74 -24
- data/lib/active_support/tagged_logging.rb +44 -8
- data/lib/active_support/test_case.rb +94 -2
- data/lib/active_support/testing/assertions.rb +58 -20
- data/lib/active_support/testing/autorun.rb +2 -4
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -1
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +8 -4
- data/lib/active_support/testing/method_call_assertions.rb +30 -1
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +12 -7
- data/lib/active_support/testing/stream.rb +3 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +78 -13
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +113 -41
- data/lib/active_support/values/time_zone.rb +55 -25
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +5 -4
- data/lib/active_support/xml_mini/libxml.rb +4 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
- data/lib/active_support/xml_mini/nokogiri.rb +4 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
- data/lib/active_support/xml_mini/rexml.rb +12 -3
- data/lib/active_support/xml_mini.rb +5 -11
- data/lib/active_support.rb +18 -13
- metadata +81 -35
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/values/unicode_tables.dat +0 -0
data/lib/active_support/cache.rb
CHANGED
@@ -1,23 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "zlib"
|
2
4
|
require "active_support/core_ext/array/extract_options"
|
3
5
|
require "active_support/core_ext/array/wrap"
|
6
|
+
require "active_support/core_ext/enumerable"
|
4
7
|
require "active_support/core_ext/module/attribute_accessors"
|
5
8
|
require "active_support/core_ext/numeric/bytes"
|
6
9
|
require "active_support/core_ext/numeric/time"
|
7
10
|
require "active_support/core_ext/object/to_param"
|
11
|
+
require "active_support/core_ext/object/try"
|
8
12
|
require "active_support/core_ext/string/inflections"
|
9
13
|
|
10
14
|
module ActiveSupport
|
11
15
|
# See ActiveSupport::Cache::Store for documentation.
|
12
16
|
module Cache
|
13
|
-
autoload :FileStore,
|
14
|
-
autoload :MemoryStore,
|
15
|
-
autoload :MemCacheStore,
|
16
|
-
autoload :NullStore,
|
17
|
+
autoload :FileStore, "active_support/cache/file_store"
|
18
|
+
autoload :MemoryStore, "active_support/cache/memory_store"
|
19
|
+
autoload :MemCacheStore, "active_support/cache/mem_cache_store"
|
20
|
+
autoload :NullStore, "active_support/cache/null_store"
|
21
|
+
autoload :RedisCacheStore, "active_support/cache/redis_cache_store"
|
17
22
|
|
18
23
|
# These options mean something to all cache implementations. Individual cache
|
19
24
|
# implementations may support additional options.
|
20
|
-
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl]
|
25
|
+
UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl, :coder]
|
21
26
|
|
22
27
|
module Strategy
|
23
28
|
autoload :LocalCache, "active_support/cache/strategy/local_cache"
|
@@ -49,12 +54,13 @@ module ActiveSupport
|
|
49
54
|
#
|
50
55
|
# ActiveSupport::Cache.lookup_store(MyOwnCacheStore.new)
|
51
56
|
# # => returns MyOwnCacheStore.new
|
52
|
-
def lookup_store(*
|
53
|
-
store, *parameters = *Array.wrap(store_option).flatten
|
54
|
-
|
57
|
+
def lookup_store(store = nil, *parameters)
|
55
58
|
case store
|
56
59
|
when Symbol
|
57
|
-
|
60
|
+
options = parameters.extract_options!
|
61
|
+
retrieve_store_class(store).new(*parameters, **options)
|
62
|
+
when Array
|
63
|
+
lookup_store(*store)
|
58
64
|
when nil
|
59
65
|
ActiveSupport::Cache::MemoryStore.new
|
60
66
|
else
|
@@ -75,7 +81,7 @@ module ActiveSupport
|
|
75
81
|
#
|
76
82
|
# The +key+ argument can also respond to +cache_key+ or +to_param+.
|
77
83
|
def expand_cache_key(key, namespace = nil)
|
78
|
-
expanded_cache_key = namespace ? "#{namespace}/" : ""
|
84
|
+
expanded_cache_key = namespace ? +"#{namespace}/" : +""
|
79
85
|
|
80
86
|
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
81
87
|
expanded_cache_key << "#{prefix}/"
|
@@ -88,16 +94,19 @@ module ActiveSupport
|
|
88
94
|
private
|
89
95
|
def retrieve_cache_key(key)
|
90
96
|
case
|
91
|
-
when key.respond_to?(:
|
92
|
-
when key.
|
93
|
-
when key.
|
94
|
-
|
97
|
+
when key.respond_to?(:cache_key_with_version) then key.cache_key_with_version
|
98
|
+
when key.respond_to?(:cache_key) then key.cache_key
|
99
|
+
when key.is_a?(Array) then key.map { |element| retrieve_cache_key(element) }.to_param
|
100
|
+
when key.respond_to?(:to_a) then retrieve_cache_key(key.to_a)
|
101
|
+
else key.to_param
|
95
102
|
end.to_s
|
96
103
|
end
|
97
104
|
|
98
105
|
# Obtains the specified cache store class, given the name of the +store+.
|
99
106
|
# Raises an error when the store class cannot be found.
|
100
107
|
def retrieve_store_class(store)
|
108
|
+
# require_relative cannot be used here because the class might be
|
109
|
+
# provided by another gem, like redis-activesupport for example.
|
101
110
|
require "active_support/cache/#{store}"
|
102
111
|
rescue LoadError => e
|
103
112
|
raise "Could not find cache store adapter for #{store} (#{e})"
|
@@ -143,23 +152,42 @@ module ActiveSupport
|
|
143
152
|
# cache.namespace = -> { @last_mod_time } # Set the namespace to a variable
|
144
153
|
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
145
154
|
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
# <tt
|
150
|
-
#
|
151
|
-
# <tt>:compress_threshold</tt> option. The default threshold is 16K.
|
155
|
+
# Cached data larger than 1kB are compressed by default. To turn off
|
156
|
+
# compression, pass <tt>compress: false</tt> to the initializer or to
|
157
|
+
# individual +fetch+ or +write+ method calls. The 1kB compression
|
158
|
+
# threshold is configurable with the <tt>:compress_threshold</tt> option,
|
159
|
+
# specified in bytes.
|
152
160
|
class Store
|
161
|
+
DEFAULT_CODER = Marshal
|
162
|
+
|
153
163
|
cattr_accessor :logger, instance_writer: true
|
154
164
|
|
155
165
|
attr_reader :silence, :options
|
156
166
|
alias :silence? :silence
|
157
167
|
|
168
|
+
class << self
|
169
|
+
private
|
170
|
+
def retrieve_pool_options(options)
|
171
|
+
{}.tap do |pool_options|
|
172
|
+
pool_options[:size] = options.delete(:pool_size) if options[:pool_size]
|
173
|
+
pool_options[:timeout] = options.delete(:pool_timeout) if options[:pool_timeout]
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def ensure_connection_pool_added!
|
178
|
+
require "connection_pool"
|
179
|
+
rescue LoadError => e
|
180
|
+
$stderr.puts "You don't have connection_pool installed in your application. Please add it to your Gemfile and run bundle install"
|
181
|
+
raise e
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
158
185
|
# Creates a new cache. The options will be passed to any write method calls
|
159
186
|
# except for <tt>:namespace</tt> which can be used to set the global
|
160
187
|
# namespace for the cache.
|
161
188
|
def initialize(options = nil)
|
162
189
|
@options = options ? options.dup : {}
|
190
|
+
@coder = @options.delete(:coder) { self.class::DEFAULT_CODER } || NullCoder
|
163
191
|
end
|
164
192
|
|
165
193
|
# Silences the logger.
|
@@ -207,8 +235,15 @@ module ActiveSupport
|
|
207
235
|
# ask whether you should force a cache write. Otherwise, it's clearer to
|
208
236
|
# just call <tt>Cache#write</tt>.
|
209
237
|
#
|
210
|
-
# Setting <tt
|
211
|
-
#
|
238
|
+
# Setting <tt>skip_nil: true</tt> will not cache nil result:
|
239
|
+
#
|
240
|
+
# cache.fetch('foo') { nil }
|
241
|
+
# cache.fetch('bar', skip_nil: true) { nil }
|
242
|
+
# cache.exist?('foo') # => true
|
243
|
+
# cache.exist?('bar') # => false
|
244
|
+
#
|
245
|
+
#
|
246
|
+
# Setting <tt>compress: false</tt> disables compression of the cache entry.
|
212
247
|
#
|
213
248
|
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
214
249
|
# All caches support auto-expiring content after a specified number of
|
@@ -219,6 +254,10 @@ module ActiveSupport
|
|
219
254
|
# cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
|
220
255
|
# cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
|
221
256
|
#
|
257
|
+
# Setting <tt>:version</tt> verifies the cache stored under <tt>name</tt>
|
258
|
+
# is of the same version. nil is returned on mismatches despite contents.
|
259
|
+
# This feature is used to support recyclable cache keys.
|
260
|
+
#
|
222
261
|
# Setting <tt>:race_condition_ttl</tt> is very useful in situations where
|
223
262
|
# a cache entry is used very frequently and is under heavy load. If a
|
224
263
|
# cache expires and due to heavy load several different processes will try
|
@@ -278,15 +317,16 @@ module ActiveSupport
|
|
278
317
|
# :bar
|
279
318
|
# end
|
280
319
|
# cache.fetch('foo') # => "bar"
|
281
|
-
def fetch(name, options = nil)
|
320
|
+
def fetch(name, options = nil, &block)
|
282
321
|
if block_given?
|
283
322
|
options = merged_options(options)
|
284
323
|
key = normalize_key(name, options)
|
285
324
|
|
286
325
|
entry = nil
|
287
326
|
instrument(:read, name, options) do |payload|
|
288
|
-
cached_entry = read_entry(key, options) unless options[:force]
|
327
|
+
cached_entry = read_entry(key, **options, event: payload) unless options[:force]
|
289
328
|
entry = handle_expired_entry(cached_entry, key, options)
|
329
|
+
entry = nil if entry && entry.mismatched?(normalize_version(name, options))
|
290
330
|
payload[:super_operation] = :fetch if payload
|
291
331
|
payload[:hit] = !!entry if payload
|
292
332
|
end
|
@@ -294,7 +334,7 @@ module ActiveSupport
|
|
294
334
|
if entry
|
295
335
|
get_entry_value(entry, name, options)
|
296
336
|
else
|
297
|
-
save_block_result_to_cache(name, options)
|
337
|
+
save_block_result_to_cache(name, options, &block)
|
298
338
|
end
|
299
339
|
elsif options && options[:force]
|
300
340
|
raise ArgumentError, "Missing block: Calling `Cache#fetch` with `force: true` requires a block."
|
@@ -303,19 +343,29 @@ module ActiveSupport
|
|
303
343
|
end
|
304
344
|
end
|
305
345
|
|
306
|
-
#
|
346
|
+
# Reads data from the cache, using the given key. If there is data in
|
307
347
|
# the cache with the given key, then that data is returned. Otherwise,
|
308
348
|
# +nil+ is returned.
|
309
349
|
#
|
350
|
+
# Note, if data was written with the <tt>:expires_in</tt> or
|
351
|
+
# <tt>:version</tt> options, both of these conditions are applied before
|
352
|
+
# the data is returned.
|
353
|
+
#
|
310
354
|
# Options are passed to the underlying cache implementation.
|
311
355
|
def read(name, options = nil)
|
312
356
|
options = merged_options(options)
|
313
|
-
key
|
357
|
+
key = normalize_key(name, options)
|
358
|
+
version = normalize_version(name, options)
|
359
|
+
|
314
360
|
instrument(:read, name, options) do |payload|
|
315
|
-
entry = read_entry(key, options)
|
361
|
+
entry = read_entry(key, **options, event: payload)
|
362
|
+
|
316
363
|
if entry
|
317
364
|
if entry.expired?
|
318
|
-
delete_entry(key, options)
|
365
|
+
delete_entry(key, **options)
|
366
|
+
payload[:hit] = false if payload
|
367
|
+
nil
|
368
|
+
elsif entry.mismatched?(version)
|
319
369
|
payload[:hit] = false if payload
|
320
370
|
nil
|
321
371
|
else
|
@@ -339,19 +389,24 @@ module ActiveSupport
|
|
339
389
|
options = names.extract_options!
|
340
390
|
options = merged_options(options)
|
341
391
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
entry = read_entry(key, options)
|
346
|
-
if entry
|
347
|
-
if entry.expired?
|
348
|
-
delete_entry(key, options)
|
349
|
-
else
|
350
|
-
results[name] = entry.value
|
351
|
-
end
|
392
|
+
instrument :read_multi, names, options do |payload|
|
393
|
+
read_multi_entries(names, **options, event: payload).tap do |results|
|
394
|
+
payload[:hits] = results.keys
|
352
395
|
end
|
353
396
|
end
|
354
|
-
|
397
|
+
end
|
398
|
+
|
399
|
+
# Cache Storage API to write multiple values at once.
|
400
|
+
def write_multi(hash, options = nil)
|
401
|
+
options = merged_options(options)
|
402
|
+
|
403
|
+
instrument :write_multi, hash, options do |payload|
|
404
|
+
entries = hash.each_with_object({}) do |(name, value), memo|
|
405
|
+
memo[normalize_key(name, options)] = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
406
|
+
end
|
407
|
+
|
408
|
+
write_multi_entries entries, **options
|
409
|
+
end
|
355
410
|
end
|
356
411
|
|
357
412
|
# Fetches data from the cache, using the given keys. If there is data in
|
@@ -362,8 +417,6 @@ module ActiveSupport
|
|
362
417
|
# to the cache. If you do not want to write the cache when the cache is
|
363
418
|
# not found, use #read_multi.
|
364
419
|
#
|
365
|
-
# Options are passed to the underlying cache implementation.
|
366
|
-
#
|
367
420
|
# Returns a hash with the data for each of the names. For example:
|
368
421
|
#
|
369
422
|
# cache.write("bim", "bam")
|
@@ -373,19 +426,36 @@ module ActiveSupport
|
|
373
426
|
# # => { "bim" => "bam",
|
374
427
|
# # "unknown_key" => "Fallback value for key: unknown_key" }
|
375
428
|
#
|
429
|
+
# Options are passed to the underlying cache implementation. For example:
|
430
|
+
#
|
431
|
+
# cache.fetch_multi("fizz", expires_in: 5.seconds) do |key|
|
432
|
+
# "buzz"
|
433
|
+
# end
|
434
|
+
# # => {"fizz"=>"buzz"}
|
435
|
+
# cache.read("fizz")
|
436
|
+
# # => "buzz"
|
437
|
+
# sleep(6)
|
438
|
+
# cache.read("fizz")
|
439
|
+
# # => nil
|
376
440
|
def fetch_multi(*names)
|
377
441
|
raise ArgumentError, "Missing block: `Cache#fetch_multi` requires a block." unless block_given?
|
378
442
|
|
379
443
|
options = names.extract_options!
|
380
444
|
options = merged_options(options)
|
381
|
-
results = read_multi(*names, options)
|
382
445
|
|
383
|
-
names
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
446
|
+
instrument :read_multi, names, options do |payload|
|
447
|
+
reads = read_multi_entries(names, **options)
|
448
|
+
writes = {}
|
449
|
+
ordered = names.index_with do |name|
|
450
|
+
reads.fetch(name) { writes[name] = yield(name) }
|
388
451
|
end
|
452
|
+
|
453
|
+
payload[:hits] = reads.keys
|
454
|
+
payload[:super_operation] = :fetch_multi
|
455
|
+
|
456
|
+
write_multi(writes, options)
|
457
|
+
|
458
|
+
ordered
|
389
459
|
end
|
390
460
|
end
|
391
461
|
|
@@ -396,8 +466,8 @@ module ActiveSupport
|
|
396
466
|
options = merged_options(options)
|
397
467
|
|
398
468
|
instrument(:write, name, options) do
|
399
|
-
entry = Entry.new(value, options)
|
400
|
-
write_entry(normalize_key(name, options), entry, options)
|
469
|
+
entry = Entry.new(value, **options.merge(version: normalize_version(name, options)))
|
470
|
+
write_entry(normalize_key(name, options), entry, **options)
|
401
471
|
end
|
402
472
|
end
|
403
473
|
|
@@ -408,7 +478,19 @@ module ActiveSupport
|
|
408
478
|
options = merged_options(options)
|
409
479
|
|
410
480
|
instrument(:delete, name) do
|
411
|
-
delete_entry(normalize_key(name, options), options)
|
481
|
+
delete_entry(normalize_key(name, options), **options)
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
485
|
+
# Deletes multiple entries in the cache.
|
486
|
+
#
|
487
|
+
# Options are passed to the underlying cache implementation.
|
488
|
+
def delete_multi(names, options = nil)
|
489
|
+
options = merged_options(options)
|
490
|
+
names.map! { |key| normalize_key(key, options) }
|
491
|
+
|
492
|
+
instrument :delete_multi, names do
|
493
|
+
delete_multi_entries(names, **options)
|
412
494
|
end
|
413
495
|
end
|
414
496
|
|
@@ -418,9 +500,9 @@ module ActiveSupport
|
|
418
500
|
def exist?(name, options = nil)
|
419
501
|
options = merged_options(options)
|
420
502
|
|
421
|
-
instrument(:exist?, name) do
|
422
|
-
entry = read_entry(normalize_key(name, options), options)
|
423
|
-
(entry && !entry.expired?) || false
|
503
|
+
instrument(:exist?, name) do |payload|
|
504
|
+
entry = read_entry(normalize_key(name, options), **options, event: payload)
|
505
|
+
(entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
|
424
506
|
end
|
425
507
|
end
|
426
508
|
|
@@ -428,7 +510,7 @@ module ActiveSupport
|
|
428
510
|
#
|
429
511
|
# Options are passed to the underlying cache implementation.
|
430
512
|
#
|
431
|
-
#
|
513
|
+
# Some implementations may not support this method.
|
432
514
|
def delete_matched(matcher, options = nil)
|
433
515
|
raise NotImplementedError.new("#{self.class.name} does not support delete_matched")
|
434
516
|
end
|
@@ -437,7 +519,7 @@ module ActiveSupport
|
|
437
519
|
#
|
438
520
|
# Options are passed to the underlying cache implementation.
|
439
521
|
#
|
440
|
-
#
|
522
|
+
# Some implementations may not support this method.
|
441
523
|
def increment(name, amount = 1, options = nil)
|
442
524
|
raise NotImplementedError.new("#{self.class.name} does not support increment")
|
443
525
|
end
|
@@ -446,7 +528,7 @@ module ActiveSupport
|
|
446
528
|
#
|
447
529
|
# Options are passed to the underlying cache implementation.
|
448
530
|
#
|
449
|
-
#
|
531
|
+
# Some implementations may not support this method.
|
450
532
|
def decrement(name, amount = 1, options = nil)
|
451
533
|
raise NotImplementedError.new("#{self.class.name} does not support decrement")
|
452
534
|
end
|
@@ -455,7 +537,7 @@ module ActiveSupport
|
|
455
537
|
#
|
456
538
|
# Options are passed to the underlying cache implementation.
|
457
539
|
#
|
458
|
-
#
|
540
|
+
# Some implementations may not support this method.
|
459
541
|
def cleanup(options = nil)
|
460
542
|
raise NotImplementedError.new("#{self.class.name} does not support cleanup")
|
461
543
|
end
|
@@ -465,8 +547,8 @@ module ActiveSupport
|
|
465
547
|
#
|
466
548
|
# The options hash is passed to the underlying cache implementation.
|
467
549
|
#
|
468
|
-
#
|
469
|
-
def clear
|
550
|
+
# Some implementations may not support this method.
|
551
|
+
def clear(options = nil)
|
470
552
|
raise NotImplementedError.new("#{self.class.name} does not support clear")
|
471
553
|
end
|
472
554
|
|
@@ -492,28 +574,107 @@ module ActiveSupport
|
|
492
574
|
|
493
575
|
# Reads an entry from the cache implementation. Subclasses must implement
|
494
576
|
# this method.
|
495
|
-
def read_entry(key, options)
|
577
|
+
def read_entry(key, **options)
|
496
578
|
raise NotImplementedError.new
|
497
579
|
end
|
498
580
|
|
499
581
|
# Writes an entry to the cache implementation. Subclasses must implement
|
500
582
|
# this method.
|
501
|
-
def write_entry(key, entry, options)
|
583
|
+
def write_entry(key, entry, **options)
|
502
584
|
raise NotImplementedError.new
|
503
585
|
end
|
504
586
|
|
587
|
+
def serialize_entry(entry)
|
588
|
+
@coder.dump(entry)
|
589
|
+
end
|
590
|
+
|
591
|
+
def deserialize_entry(payload)
|
592
|
+
payload.nil? ? nil : @coder.load(payload)
|
593
|
+
end
|
594
|
+
|
595
|
+
# Reads multiple entries from the cache implementation. Subclasses MAY
|
596
|
+
# implement this method.
|
597
|
+
def read_multi_entries(names, **options)
|
598
|
+
names.each_with_object({}) do |name, results|
|
599
|
+
key = normalize_key(name, options)
|
600
|
+
entry = read_entry(key, **options)
|
601
|
+
|
602
|
+
next unless entry
|
603
|
+
|
604
|
+
version = normalize_version(name, options)
|
605
|
+
|
606
|
+
if entry.expired?
|
607
|
+
delete_entry(key, **options)
|
608
|
+
elsif !entry.mismatched?(version)
|
609
|
+
results[name] = entry.value
|
610
|
+
end
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
# Writes multiple entries to the cache implementation. Subclasses MAY
|
615
|
+
# implement this method.
|
616
|
+
def write_multi_entries(hash, **options)
|
617
|
+
hash.each do |key, entry|
|
618
|
+
write_entry key, entry, **options
|
619
|
+
end
|
620
|
+
end
|
621
|
+
|
505
622
|
# Deletes an entry from the cache implementation. Subclasses must
|
506
623
|
# implement this method.
|
507
|
-
def delete_entry(key, options)
|
624
|
+
def delete_entry(key, **options)
|
508
625
|
raise NotImplementedError.new
|
509
626
|
end
|
510
627
|
|
628
|
+
# Deletes multiples entries in the cache implementation. Subclasses MAY
|
629
|
+
# implement this method.
|
630
|
+
def delete_multi_entries(entries, **options)
|
631
|
+
entries.count { |key| delete_entry(key, **options) }
|
632
|
+
end
|
633
|
+
|
511
634
|
# Merges the default options with ones specific to a method call.
|
512
635
|
def merged_options(call_options)
|
513
636
|
if call_options
|
514
|
-
options.
|
637
|
+
if options.empty?
|
638
|
+
call_options
|
639
|
+
else
|
640
|
+
options.merge(call_options)
|
641
|
+
end
|
515
642
|
else
|
516
|
-
options
|
643
|
+
options
|
644
|
+
end
|
645
|
+
end
|
646
|
+
|
647
|
+
# Expands and namespaces the cache key. May be overridden by
|
648
|
+
# cache stores to do additional normalization.
|
649
|
+
def normalize_key(key, options = nil)
|
650
|
+
namespace_key expanded_key(key), options
|
651
|
+
end
|
652
|
+
|
653
|
+
# Prefix the key with a namespace string:
|
654
|
+
#
|
655
|
+
# namespace_key 'foo', namespace: 'cache'
|
656
|
+
# # => 'cache:foo'
|
657
|
+
#
|
658
|
+
# With a namespace block:
|
659
|
+
#
|
660
|
+
# namespace_key 'foo', namespace: -> { 'cache' }
|
661
|
+
# # => 'cache:foo'
|
662
|
+
def namespace_key(key, options = nil)
|
663
|
+
options = merged_options(options)
|
664
|
+
namespace = options[:namespace]
|
665
|
+
|
666
|
+
if namespace.respond_to?(:call)
|
667
|
+
namespace = namespace.call
|
668
|
+
end
|
669
|
+
|
670
|
+
if key && key.encoding != Encoding::UTF_8
|
671
|
+
key = key.dup.force_encoding(Encoding::UTF_8)
|
672
|
+
end
|
673
|
+
|
674
|
+
if namespace
|
675
|
+
"#{namespace}:#{key}"
|
676
|
+
else
|
677
|
+
key
|
517
678
|
end
|
518
679
|
end
|
519
680
|
|
@@ -526,40 +687,39 @@ module ActiveSupport
|
|
526
687
|
case key
|
527
688
|
when Array
|
528
689
|
if key.size > 1
|
529
|
-
key
|
690
|
+
key.collect { |element| expanded_key(element) }
|
530
691
|
else
|
531
|
-
key
|
692
|
+
expanded_key(key.first)
|
532
693
|
end
|
533
694
|
when Hash
|
534
|
-
key
|
535
|
-
|
695
|
+
key.collect { |k, v| "#{k}=#{v}" }.sort!
|
696
|
+
else
|
697
|
+
key
|
698
|
+
end.to_param
|
699
|
+
end
|
536
700
|
|
537
|
-
|
701
|
+
def normalize_version(key, options = nil)
|
702
|
+
(options && options[:version].try(:to_param)) || expanded_version(key)
|
538
703
|
end
|
539
704
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
key
|
544
|
-
|
545
|
-
|
546
|
-
key = "#{prefix}:#{key}" if prefix
|
547
|
-
key
|
705
|
+
def expanded_version(key)
|
706
|
+
case
|
707
|
+
when key.respond_to?(:cache_version) then key.cache_version.to_param
|
708
|
+
when key.is_a?(Array) then key.map { |element| expanded_version(element) }.tap(&:compact!).to_param
|
709
|
+
when key.respond_to?(:to_a) then expanded_version(key.to_a)
|
710
|
+
end
|
548
711
|
end
|
549
712
|
|
550
713
|
def instrument(operation, key, options = nil)
|
551
|
-
|
714
|
+
if logger && logger.debug? && !silence?
|
715
|
+
logger.debug "Cache #{operation}: #{normalize_key(key, options)}#{options.blank? ? "" : " (#{options.inspect})"}"
|
716
|
+
end
|
552
717
|
|
553
|
-
payload = { key: key }
|
718
|
+
payload = { key: key, store: self.class.name }
|
554
719
|
payload.merge!(options) if options.is_a?(Hash)
|
555
720
|
ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload) { yield(payload) }
|
556
721
|
end
|
557
722
|
|
558
|
-
def log
|
559
|
-
return unless logger && logger.debug? && !silence?
|
560
|
-
logger.debug(yield)
|
561
|
-
end
|
562
|
-
|
563
723
|
def handle_expired_entry(entry, key, options)
|
564
724
|
if entry && entry.expired?
|
565
725
|
race_ttl = options[:race_condition_ttl].to_i
|
@@ -569,7 +729,7 @@ module ActiveSupport
|
|
569
729
|
entry.expires_at = Time.now + race_ttl
|
570
730
|
write_entry(key, entry, expires_in: race_ttl * 2)
|
571
731
|
else
|
572
|
-
delete_entry(key, options)
|
732
|
+
delete_entry(key, **options)
|
573
733
|
end
|
574
734
|
entry = nil
|
575
735
|
end
|
@@ -577,7 +737,7 @@ module ActiveSupport
|
|
577
737
|
end
|
578
738
|
|
579
739
|
def get_entry_value(entry, name, options)
|
580
|
-
instrument(:fetch_hit, name, options) {}
|
740
|
+
instrument(:fetch_hit, name, options) { }
|
581
741
|
entry.value
|
582
742
|
end
|
583
743
|
|
@@ -586,39 +746,54 @@ module ActiveSupport
|
|
586
746
|
yield(name)
|
587
747
|
end
|
588
748
|
|
589
|
-
write(name, result, options)
|
749
|
+
write(name, result, options) unless result.nil? && options[:skip_nil]
|
590
750
|
result
|
591
751
|
end
|
592
752
|
end
|
593
753
|
|
594
|
-
|
595
|
-
|
596
|
-
|
754
|
+
module NullCoder # :nodoc:
|
755
|
+
class << self
|
756
|
+
def load(payload)
|
757
|
+
payload
|
758
|
+
end
|
759
|
+
|
760
|
+
def dump(entry)
|
761
|
+
entry
|
762
|
+
end
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
# This class is used to represent cache entries. Cache entries have a value, an optional
|
767
|
+
# expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option
|
768
|
+
# on the cache. The version is used to support the :version option on the cache for rejecting
|
769
|
+
# mismatches.
|
597
770
|
#
|
598
771
|
# Since cache entries in most instances will be serialized, the internals of this class are highly optimized
|
599
772
|
# using short instance variable names that are lazily defined.
|
600
773
|
class Entry # :nodoc:
|
601
|
-
|
774
|
+
attr_reader :version
|
602
775
|
|
603
|
-
|
604
|
-
# +:compress+, +:compress_threshold+, and +:expires_in+.
|
605
|
-
def initialize(value, options = {})
|
606
|
-
if should_compress?(value, options)
|
607
|
-
@value = compress(value)
|
608
|
-
@compressed = true
|
609
|
-
else
|
610
|
-
@value = value
|
611
|
-
end
|
776
|
+
DEFAULT_COMPRESS_LIMIT = 1.kilobyte
|
612
777
|
|
778
|
+
# Creates a new cache entry for the specified value. Options supported are
|
779
|
+
# +:compress+, +:compress_threshold+, +:version+ and +:expires_in+.
|
780
|
+
def initialize(value, compress: true, compress_threshold: DEFAULT_COMPRESS_LIMIT, version: nil, expires_in: nil, **)
|
781
|
+
@value = value
|
782
|
+
@version = version
|
613
783
|
@created_at = Time.now.to_f
|
614
|
-
@expires_in =
|
615
|
-
|
784
|
+
@expires_in = expires_in && expires_in.to_f
|
785
|
+
|
786
|
+
compress!(compress_threshold) if compress
|
616
787
|
end
|
617
788
|
|
618
789
|
def value
|
619
790
|
compressed? ? uncompress(@value) : @value
|
620
791
|
end
|
621
792
|
|
793
|
+
def mismatched?(version)
|
794
|
+
@version && version && @version != version
|
795
|
+
end
|
796
|
+
|
622
797
|
# Checks if the entry is expired. The +expires_in+ parameter can override
|
623
798
|
# the value set when the entry was created.
|
624
799
|
def expired?
|
@@ -638,19 +813,15 @@ module ActiveSupport
|
|
638
813
|
end
|
639
814
|
|
640
815
|
# Returns the size of the cached value. This could be less than
|
641
|
-
# <tt>value.
|
642
|
-
def
|
643
|
-
|
644
|
-
|
816
|
+
# <tt>value.bytesize</tt> if the data is compressed.
|
817
|
+
def bytesize
|
818
|
+
case value
|
819
|
+
when NilClass
|
820
|
+
0
|
821
|
+
when String
|
822
|
+
@value.bytesize
|
645
823
|
else
|
646
|
-
|
647
|
-
when NilClass
|
648
|
-
0
|
649
|
-
when String
|
650
|
-
@value.bytesize
|
651
|
-
else
|
652
|
-
@s = Marshal.dump(@value).bytesize
|
653
|
-
end
|
824
|
+
@s ||= Marshal.dump(@value).bytesize
|
654
825
|
end
|
655
826
|
end
|
656
827
|
|
@@ -667,23 +838,30 @@ module ActiveSupport
|
|
667
838
|
end
|
668
839
|
|
669
840
|
private
|
670
|
-
def
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
841
|
+
def compress!(compress_threshold)
|
842
|
+
case @value
|
843
|
+
when nil, true, false, Numeric
|
844
|
+
uncompressed_size = 0
|
845
|
+
when String
|
846
|
+
uncompressed_size = @value.bytesize
|
847
|
+
else
|
848
|
+
serialized = Marshal.dump(@value)
|
849
|
+
uncompressed_size = serialized.bytesize
|
676
850
|
end
|
677
851
|
|
678
|
-
|
679
|
-
|
852
|
+
if uncompressed_size >= compress_threshold
|
853
|
+
serialized ||= Marshal.dump(@value)
|
854
|
+
compressed = Zlib::Deflate.deflate(serialized)
|
680
855
|
|
681
|
-
|
682
|
-
|
856
|
+
if compressed.bytesize < uncompressed_size
|
857
|
+
@value = compressed
|
858
|
+
@compressed = true
|
859
|
+
end
|
860
|
+
end
|
683
861
|
end
|
684
862
|
|
685
|
-
def
|
686
|
-
|
863
|
+
def compressed?
|
864
|
+
defined?(@compressed)
|
687
865
|
end
|
688
866
|
|
689
867
|
def uncompress(value)
|