activesupport 5.1.7 → 5.2.0.beta1
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 +303 -617
- data/README.rdoc +1 -1
- data/lib/active_support.rb +3 -12
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +2 -0
- data/lib/active_support/backtrace_cleaner.rb +2 -0
- data/lib/active_support/benchmarkable.rb +2 -0
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache.rb +127 -58
- data/lib/active_support/cache/file_store.rb +4 -3
- data/lib/active_support/cache/mem_cache_store.rb +12 -4
- data/lib/active_support/cache/memory_store.rb +2 -0
- data/lib/active_support/cache/null_store.rb +2 -0
- data/lib/active_support/cache/redis_cache_store.rb +404 -0
- data/lib/active_support/cache/strategy/local_cache.rb +9 -2
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/callbacks.rb +26 -37
- data/lib/active_support/concern.rb +3 -1
- data/lib/active_support/concurrency/share_lock.rb +2 -0
- data/lib/active_support/configurable.rb +2 -0
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/core_ext/array.rb +2 -0
- data/lib/active_support/core_ext/array/access.rb +4 -2
- data/lib/active_support/core_ext/array/conversions.rb +2 -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/prepend_and_append.rb +4 -2
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/benchmark.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +34 -16
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +1 -2
- data/lib/active_support/core_ext/date.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 +2 -0
- data/lib/active_support/core_ext/date/conversions.rb +10 -9
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +42 -16
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +3 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +2 -0
- 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 +2 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +6 -4
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +3 -1
- data/lib/active_support/core_ext/enumerable.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/file/atomic.rb +2 -0
- data/lib/active_support/core_ext/hash.rb +2 -0
- data/lib/active_support/core_ext/hash/compact.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +2 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/except.rb +2 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +2 -0
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +4 -4
- data/lib/active_support/core_ext/hash/transform_values.rb +2 -0
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/kernel.rb +2 -0
- data/lib/active_support/core_ext/kernel/agnostics.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/load_error.rb +2 -7
- data/lib/active_support/core_ext/marshal.rb +2 -0
- data/lib/active_support/core_ext/module.rb +3 -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 +2 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +21 -24
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +2 -0
- data/lib/active_support/core_ext/module/concerning.rb +2 -0
- data/lib/active_support/core_ext/module/delegation.rb +29 -24
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +2 -0
- data/lib/active_support/core_ext/module/reachable.rb +3 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/name_error.rb +2 -0
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +9 -7
- data/lib/active_support/core_ext/numeric/inquiry.rb +2 -0
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/object.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +2 -0
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +2 -0
- data/lib/active_support/core_ext/object/duplicable.rb +10 -8
- 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 +8 -0
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +4 -5
- data/lib/active_support/core_ext/object/try.rb +2 -0
- data/lib/active_support/core_ext/object/with_options.rb +3 -1
- data/lib/active_support/core_ext/range.rb +3 -0
- data/lib/active_support/core_ext/range/conversions.rb +9 -1
- data/lib/active_support/core_ext/range/each.rb +5 -1
- data/lib/active_support/core_ext/range/include_range.rb +2 -0
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- data/lib/active_support/core_ext/string/access.rb +2 -0
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +2 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +2 -0
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +26 -12
- data/lib/active_support/core_ext/string/inquiry.rb +2 -0
- data/lib/active_support/core_ext/string/multibyte.rb +2 -0
- data/lib/active_support/core_ext/string/output_safety.rb +6 -7
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +2 -0
- data/lib/active_support/core_ext/string/zones.rb +2 -0
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +23 -15
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +2 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/uri.rb +4 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies.rb +15 -25
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/deprecation.rb +4 -2
- data/lib/active_support/deprecation/behaviors.rb +23 -8
- data/lib/active_support/deprecation/constant_accessor.rb +3 -1
- data/lib/active_support/deprecation/instance_delegator.rb +2 -0
- data/lib/active_support/deprecation/method_wrappers.rb +2 -7
- data/lib/active_support/deprecation/proxy_wrappers.rb +4 -1
- data/lib/active_support/deprecation/reporting.rb +4 -2
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/duration.rb +8 -14
- data/lib/active_support/duration/iso8601_parser.rb +4 -2
- data/lib/active_support/duration/iso8601_serializer.rb +4 -2
- data/lib/active_support/encrypted_configuration.rb +48 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +2 -0
- data/lib/active_support/execution_wrapper.rb +2 -0
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -0
- data/lib/active_support/gem_version.rb +5 -3
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +33 -1
- data/lib/active_support/i18n.rb +3 -1
- data/lib/active_support/i18n_railtie.rb +5 -11
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +19 -3
- data/lib/active_support/inflector/methods.rb +40 -23
- data/lib/active_support/inflector/transliterate.rb +17 -8
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/json/decoding.rb +2 -0
- data/lib/active_support/json/encoding.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -1
- data/lib/active_support/lazy_load_hooks.rb +2 -0
- data/lib/active_support/log_subscriber.rb +3 -2
- data/lib/active_support/log_subscriber/test_helper.rb +2 -0
- data/lib/active_support/logger.rb +2 -0
- data/lib/active_support/logger_silence.rb +3 -2
- data/lib/active_support/logger_thread_safe_level.rb +2 -0
- data/lib/active_support/message_encryptor.rb +94 -22
- data/lib/active_support/message_verifier.rb +78 -7
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/multibyte/chars.rb +2 -0
- data/lib/active_support/multibyte/unicode.rb +3 -1
- data/lib/active_support/notifications.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +2 -0
- data/lib/active_support/notifications/instrumenter.rb +2 -0
- data/lib/active_support/number_helper.rb +2 -0
- data/lib/active_support/number_helper/number_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +2 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -20
- data/lib/active_support/number_helper/rounding_helper.rb +5 -3
- data/lib/active_support/option_merger.rb +2 -0
- data/lib/active_support/ordered_hash.rb +2 -0
- data/lib/active_support/ordered_options.rb +4 -2
- data/lib/active_support/per_thread_registry.rb +2 -0
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +2 -0
- data/lib/active_support/railtie.rb +27 -8
- data/lib/active_support/reloader.rb +7 -5
- data/lib/active_support/rescuable.rb +3 -2
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +2 -0
- data/lib/active_support/subscriber.rb +2 -0
- data/lib/active_support/tagged_logging.rb +2 -0
- data/lib/active_support/test_case.rb +2 -1
- data/lib/active_support/testing/assertions.rb +6 -4
- data/lib/active_support/testing/autorun.rb +2 -0
- 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 -0
- data/lib/active_support/testing/file_fixtures.rb +2 -0
- data/lib/active_support/testing/isolation.rb +5 -5
- data/lib/active_support/testing/method_call_assertions.rb +2 -0
- data/lib/active_support/testing/setup_and_teardown.rb +2 -0
- data/lib/active_support/testing/stream.rb +2 -0
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +31 -2
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +38 -0
- data/lib/active_support/values/time_zone.rb +20 -12
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +4 -2
- data/lib/active_support/xml_mini/libxml.rb +3 -1
- data/lib/active_support/xml_mini/libxmlsax.rb +4 -2
- data/lib/active_support/xml_mini/nokogiri.rb +3 -1
- data/lib/active_support/xml_mini/nokogirisax.rb +3 -1
- data/lib/active_support/xml_mini/rexml.rb +3 -1
- metadata +19 -15
data/README.rdoc
CHANGED
data/lib/active_support.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2005-2017 David Heinemeier Hansson
|
3
5
|
#
|
@@ -32,6 +34,7 @@ module ActiveSupport
|
|
32
34
|
extend ActiveSupport::Autoload
|
33
35
|
|
34
36
|
autoload :Concern
|
37
|
+
autoload :CurrentAttributes
|
35
38
|
autoload :Dependencies
|
36
39
|
autoload :DescendantsTracker
|
37
40
|
autoload :ExecutionWrapper
|
@@ -79,18 +82,6 @@ module ActiveSupport
|
|
79
82
|
|
80
83
|
cattr_accessor :test_order # :nodoc:
|
81
84
|
|
82
|
-
def self.halt_callback_chains_on_return_false
|
83
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
84
|
-
ActiveSupport.halt_callback_chains_on_return_false is deprecated and will be removed in Rails 5.2.
|
85
|
-
MSG
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.halt_callback_chains_on_return_false=(value)
|
89
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
90
|
-
ActiveSupport.halt_callback_chains_on_return_false= is deprecated and will be removed in Rails 5.2.
|
91
|
-
MSG
|
92
|
-
end
|
93
|
-
|
94
85
|
def self.to_time_preserves_timezone
|
95
86
|
DateAndTime::Compatibility.preserve_timezone
|
96
87
|
end
|
data/lib/active_support/all.rb
CHANGED
data/lib/active_support/cache.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
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"
|
@@ -10,10 +12,11 @@ require "active_support/core_ext/string/inflections"
|
|
10
12
|
module ActiveSupport
|
11
13
|
# See ActiveSupport::Cache::Store for documentation.
|
12
14
|
module Cache
|
13
|
-
autoload :FileStore,
|
14
|
-
autoload :MemoryStore,
|
15
|
-
autoload :MemCacheStore,
|
16
|
-
autoload :NullStore,
|
15
|
+
autoload :FileStore, "active_support/cache/file_store"
|
16
|
+
autoload :MemoryStore, "active_support/cache/memory_store"
|
17
|
+
autoload :MemCacheStore, "active_support/cache/mem_cache_store"
|
18
|
+
autoload :NullStore, "active_support/cache/null_store"
|
19
|
+
autoload :RedisCacheStore, "active_support/cache/redis_cache_store"
|
17
20
|
|
18
21
|
# These options mean something to all cache implementations. Individual cache
|
19
22
|
# implementations may support additional options.
|
@@ -75,7 +78,7 @@ module ActiveSupport
|
|
75
78
|
#
|
76
79
|
# The +key+ argument can also respond to +cache_key+ or +to_param+.
|
77
80
|
def expand_cache_key(key, namespace = nil)
|
78
|
-
expanded_cache_key = namespace ? "#{namespace}/" : ""
|
81
|
+
expanded_cache_key = (namespace ? "#{namespace}/" : "").dup
|
79
82
|
|
80
83
|
if prefix = ENV["RAILS_CACHE_ID"] || ENV["RAILS_APP_VERSION"]
|
81
84
|
expanded_cache_key << "#{prefix}/"
|
@@ -88,16 +91,24 @@ module ActiveSupport
|
|
88
91
|
private
|
89
92
|
def retrieve_cache_key(key)
|
90
93
|
case
|
91
|
-
when key.respond_to?(:
|
92
|
-
|
93
|
-
when key.respond_to?(:
|
94
|
-
|
94
|
+
when key.respond_to?(:cache_key_with_version)
|
95
|
+
key.cache_key_with_version
|
96
|
+
when key.respond_to?(:cache_key)
|
97
|
+
key.cache_key
|
98
|
+
when key.is_a?(Hash)
|
99
|
+
key.sort_by { |k, _| k.to_s }.collect { |k, v| "#{k}=#{v}" }.to_param
|
100
|
+
when key.respond_to?(:to_a)
|
101
|
+
key.to_a.collect { |element| retrieve_cache_key(element) }.to_param
|
102
|
+
else
|
103
|
+
key.to_param
|
95
104
|
end.to_s
|
96
105
|
end
|
97
106
|
|
98
107
|
# Obtains the specified cache store class, given the name of the +store+.
|
99
108
|
# Raises an error when the store class cannot be found.
|
100
109
|
def retrieve_store_class(store)
|
110
|
+
# require_relative cannot be used here because the class might be
|
111
|
+
# provided by another gem, like redis-activesupport for example.
|
101
112
|
require "active_support/cache/#{store}"
|
102
113
|
rescue LoadError => e
|
103
114
|
raise "Could not find cache store adapter for #{store} (#{e})"
|
@@ -143,12 +154,11 @@ module ActiveSupport
|
|
143
154
|
# cache.namespace = -> { @last_mod_time } # Set the namespace to a variable
|
144
155
|
# @last_mod_time = Time.now # Invalidate the entire cache by changing namespace
|
145
156
|
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
# <tt
|
150
|
-
#
|
151
|
-
# <tt>:compress_threshold</tt> option. The default threshold is 16K.
|
157
|
+
# Cached data larger than 1kB are compressed by default. To turn off
|
158
|
+
# compression, pass <tt>compress: false</tt> to the initializer or to
|
159
|
+
# individual +fetch+ or +write+ method calls. The 1kB compression
|
160
|
+
# threshold is configurable with the <tt>:compress_threshold</tt> option,
|
161
|
+
# specified in bytes.
|
152
162
|
class Store
|
153
163
|
cattr_accessor :logger, instance_writer: true
|
154
164
|
|
@@ -207,8 +217,7 @@ module ActiveSupport
|
|
207
217
|
# ask whether you should force a cache write. Otherwise, it's clearer to
|
208
218
|
# just call <tt>Cache#write</tt>.
|
209
219
|
#
|
210
|
-
# Setting <tt
|
211
|
-
# in a compressed format.
|
220
|
+
# Setting <tt>compress: false</tt> disables compression of the cache entry.
|
212
221
|
#
|
213
222
|
# Setting <tt>:expires_in</tt> will set an expiration time on the cache.
|
214
223
|
# All caches support auto-expiring content after a specified number of
|
@@ -219,6 +228,10 @@ module ActiveSupport
|
|
219
228
|
# cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
|
220
229
|
# cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
|
221
230
|
#
|
231
|
+
# Setting <tt>:version</tt> verifies the cache stored under <tt>name</tt>
|
232
|
+
# is of the same version. nil is returned on mismatches despite contents.
|
233
|
+
# This feature is used to support recyclable cache keys.
|
234
|
+
#
|
222
235
|
# Setting <tt>:race_condition_ttl</tt> is very useful in situations where
|
223
236
|
# a cache entry is used very frequently and is under heavy load. If a
|
224
237
|
# cache expires and due to heavy load several different processes will try
|
@@ -287,6 +300,7 @@ module ActiveSupport
|
|
287
300
|
instrument(:read, name, options) do |payload|
|
288
301
|
cached_entry = read_entry(key, options) unless options[:force]
|
289
302
|
entry = handle_expired_entry(cached_entry, key, options)
|
303
|
+
entry = nil if entry && entry.mismatched?(normalize_version(name, options))
|
290
304
|
payload[:super_operation] = :fetch if payload
|
291
305
|
payload[:hit] = !!entry if payload
|
292
306
|
end
|
@@ -303,21 +317,30 @@ module ActiveSupport
|
|
303
317
|
end
|
304
318
|
end
|
305
319
|
|
306
|
-
#
|
320
|
+
# Reads data from the cache, using the given key. If there is data in
|
307
321
|
# the cache with the given key, then that data is returned. Otherwise,
|
308
322
|
# +nil+ is returned.
|
309
323
|
#
|
324
|
+
# Note, if data was written with the <tt>:expires_in<tt> or <tt>:version</tt> options,
|
325
|
+
# both of these conditions are applied before the data is returned.
|
326
|
+
#
|
310
327
|
# Options are passed to the underlying cache implementation.
|
311
328
|
def read(name, options = nil)
|
312
329
|
options = merged_options(options)
|
313
|
-
key
|
330
|
+
key = normalize_key(name, options)
|
331
|
+
version = normalize_version(name, options)
|
332
|
+
|
314
333
|
instrument(:read, name, options) do |payload|
|
315
334
|
entry = read_entry(key, options)
|
335
|
+
|
316
336
|
if entry
|
317
337
|
if entry.expired?
|
318
338
|
delete_entry(key, options)
|
319
339
|
payload[:hit] = false if payload
|
320
340
|
nil
|
341
|
+
elsif entry.mismatched?(version)
|
342
|
+
payload[:hit] = false if payload
|
343
|
+
nil
|
321
344
|
else
|
322
345
|
payload[:hit] = true if payload
|
323
346
|
entry.value
|
@@ -341,11 +364,15 @@ module ActiveSupport
|
|
341
364
|
|
342
365
|
results = {}
|
343
366
|
names.each do |name|
|
344
|
-
key
|
345
|
-
|
367
|
+
key = normalize_key(name, options)
|
368
|
+
version = normalize_version(name, options)
|
369
|
+
entry = read_entry(key, options)
|
370
|
+
|
346
371
|
if entry
|
347
372
|
if entry.expired?
|
348
373
|
delete_entry(key, options)
|
374
|
+
elsif entry.mismatched?(version)
|
375
|
+
# Skip mismatched versions
|
349
376
|
else
|
350
377
|
results[name] = entry.value
|
351
378
|
end
|
@@ -354,6 +381,19 @@ module ActiveSupport
|
|
354
381
|
results
|
355
382
|
end
|
356
383
|
|
384
|
+
# Cache Storage API to write multiple values at once.
|
385
|
+
def write_multi(hash, options = nil)
|
386
|
+
options = merged_options(options)
|
387
|
+
|
388
|
+
instrument :write_multi, hash, options do |payload|
|
389
|
+
entries = hash.each_with_object({}) do |(name, value), memo|
|
390
|
+
memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
391
|
+
end
|
392
|
+
|
393
|
+
write_multi_entries entries, options
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
357
397
|
# Fetches data from the cache, using the given keys. If there is data in
|
358
398
|
# the cache with the given keys, then that data is returned. Otherwise,
|
359
399
|
# the supplied block is called for each key for which there was no data,
|
@@ -378,14 +418,15 @@ module ActiveSupport
|
|
378
418
|
|
379
419
|
options = names.extract_options!
|
380
420
|
options = merged_options(options)
|
381
|
-
results = read_multi(*names, options)
|
382
421
|
|
383
|
-
names.
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
422
|
+
read_multi(*names, options).tap do |results|
|
423
|
+
writes = {}
|
424
|
+
|
425
|
+
(names - results.keys).each do |name|
|
426
|
+
results[name] = writes[name] = yield(name)
|
388
427
|
end
|
428
|
+
|
429
|
+
write_multi writes, options
|
389
430
|
end
|
390
431
|
end
|
391
432
|
|
@@ -396,7 +437,7 @@ module ActiveSupport
|
|
396
437
|
options = merged_options(options)
|
397
438
|
|
398
439
|
instrument(:write, name, options) do
|
399
|
-
entry = Entry.new(value, options)
|
440
|
+
entry = Entry.new(value, options.merge(version: normalize_version(name, options)))
|
400
441
|
write_entry(normalize_key(name, options), entry, options)
|
401
442
|
end
|
402
443
|
end
|
@@ -420,7 +461,7 @@ module ActiveSupport
|
|
420
461
|
|
421
462
|
instrument(:exist?, name) do
|
422
463
|
entry = read_entry(normalize_key(name, options), options)
|
423
|
-
(entry && !entry.expired?) || false
|
464
|
+
(entry && !entry.expired? && !entry.mismatched?(normalize_version(name, options))) || false
|
424
465
|
end
|
425
466
|
end
|
426
467
|
|
@@ -502,6 +543,14 @@ module ActiveSupport
|
|
502
543
|
raise NotImplementedError.new
|
503
544
|
end
|
504
545
|
|
546
|
+
# Writes multiple entries to the cache implementation. Subclasses MAY
|
547
|
+
# implement this method.
|
548
|
+
def write_multi_entries(hash, options)
|
549
|
+
hash.each do |key, entry|
|
550
|
+
write_entry key, entry, options
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
505
554
|
# Deletes an entry from the cache implementation. Subclasses must
|
506
555
|
# implement this method.
|
507
556
|
def delete_entry(key, options)
|
@@ -517,34 +566,46 @@ module ActiveSupport
|
|
517
566
|
end
|
518
567
|
end
|
519
568
|
|
520
|
-
# Expands
|
521
|
-
#
|
522
|
-
|
523
|
-
|
524
|
-
|
569
|
+
# Expands and namespaces the cache key. May be overridden by
|
570
|
+
# cache stores to do additional normalization.
|
571
|
+
def normalize_key(key, options = nil)
|
572
|
+
namespace_key Cache.expand_cache_key(key), options
|
573
|
+
end
|
525
574
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
575
|
+
# Prefix the key with a namespace string:
|
576
|
+
#
|
577
|
+
# namespace_key 'foo', namespace: 'cache'
|
578
|
+
# # => 'cache:foo'
|
579
|
+
#
|
580
|
+
# With a namespace block:
|
581
|
+
#
|
582
|
+
# namespace_key 'foo', namespace: -> { 'cache' }
|
583
|
+
# # => 'cache:foo'
|
584
|
+
def namespace_key(key, options = nil)
|
585
|
+
options = merged_options(options)
|
586
|
+
namespace = options[:namespace]
|
587
|
+
|
588
|
+
if namespace.respond_to?(:call)
|
589
|
+
namespace = namespace.call
|
535
590
|
end
|
536
591
|
|
537
|
-
|
592
|
+
if namespace
|
593
|
+
"#{namespace}:#{key}"
|
594
|
+
else
|
595
|
+
key
|
596
|
+
end
|
538
597
|
end
|
539
598
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
key
|
547
|
-
key
|
599
|
+
def normalize_version(key, options = nil)
|
600
|
+
(options && options[:version].try(:to_param)) || expanded_version(key)
|
601
|
+
end
|
602
|
+
|
603
|
+
def expanded_version(key)
|
604
|
+
case
|
605
|
+
when key.respond_to?(:cache_version) then key.cache_version.to_param
|
606
|
+
when key.is_a?(Array) then key.map { |element| expanded_version(element) }.compact.to_param
|
607
|
+
when key.respond_to?(:to_a) then expanded_version(key.to_a)
|
608
|
+
end
|
548
609
|
end
|
549
610
|
|
550
611
|
def instrument(operation, key, options = nil)
|
@@ -591,14 +652,17 @@ module ActiveSupport
|
|
591
652
|
end
|
592
653
|
end
|
593
654
|
|
594
|
-
# This class is used to represent cache entries. Cache entries have a value
|
595
|
-
# expiration time. The expiration time is used to support the :race_condition_ttl option
|
596
|
-
# on the cache.
|
655
|
+
# This class is used to represent cache entries. Cache entries have a value, an optional
|
656
|
+
# expiration time, and an optional version. The expiration time is used to support the :race_condition_ttl option
|
657
|
+
# on the cache. The version is used to support the :version option on the cache for rejecting
|
658
|
+
# mismatches.
|
597
659
|
#
|
598
660
|
# Since cache entries in most instances will be serialized, the internals of this class are highly optimized
|
599
661
|
# using short instance variable names that are lazily defined.
|
600
662
|
class Entry # :nodoc:
|
601
|
-
|
663
|
+
attr_reader :version
|
664
|
+
|
665
|
+
DEFAULT_COMPRESS_LIMIT = 1.kilobyte
|
602
666
|
|
603
667
|
# Creates a new cache entry for the specified value. Options supported are
|
604
668
|
# +:compress+, +:compress_threshold+, and +:expires_in+.
|
@@ -610,6 +674,7 @@ module ActiveSupport
|
|
610
674
|
@value = value
|
611
675
|
end
|
612
676
|
|
677
|
+
@version = options[:version]
|
613
678
|
@created_at = Time.now.to_f
|
614
679
|
@expires_in = options[:expires_in]
|
615
680
|
@expires_in = @expires_in.to_f if @expires_in
|
@@ -619,6 +684,10 @@ module ActiveSupport
|
|
619
684
|
compressed? ? uncompress(@value) : @value
|
620
685
|
end
|
621
686
|
|
687
|
+
def mismatched?(version)
|
688
|
+
@version && version && @version != version
|
689
|
+
end
|
690
|
+
|
622
691
|
# Checks if the entry is expired. The +expires_in+ parameter can override
|
623
692
|
# the value set when the entry was created.
|
624
693
|
def expired?
|
@@ -668,8 +737,8 @@ module ActiveSupport
|
|
668
737
|
|
669
738
|
private
|
670
739
|
def should_compress?(value, options)
|
671
|
-
if value && options
|
672
|
-
compress_threshold = options
|
740
|
+
if value && options.fetch(:compress, true)
|
741
|
+
compress_threshold = options.fetch(:compress_threshold, DEFAULT_COMPRESS_LIMIT)
|
673
742
|
serialized_value_size = (value.is_a?(String) ? value : Marshal.dump(value)).bytesize
|
674
743
|
|
675
744
|
return true if serialized_value_size >= compress_threshold
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/marshal"
|
2
4
|
require "active_support/core_ext/file/atomic"
|
3
5
|
require "active_support/core_ext/string/conversions"
|
@@ -37,9 +39,8 @@ module ActiveSupport
|
|
37
39
|
def cleanup(options = nil)
|
38
40
|
options = merged_options(options)
|
39
41
|
search_dir(cache_path) do |fname|
|
40
|
-
|
41
|
-
|
42
|
-
delete_entry(key, options) if entry && entry.expired?
|
42
|
+
entry = read_entry(fname, options)
|
43
|
+
delete_entry(fname, options) if entry && entry.expired?
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require "dalli"
|
3
5
|
rescue LoadError => e
|
@@ -12,7 +14,7 @@ require "active_support/core_ext/array/extract_options"
|
|
12
14
|
module ActiveSupport
|
13
15
|
module Cache
|
14
16
|
# A cache store implementation which stores data in Memcached:
|
15
|
-
#
|
17
|
+
# https://memcached.org
|
16
18
|
#
|
17
19
|
# This is currently the most popular cache store for production websites.
|
18
20
|
#
|
@@ -97,12 +99,18 @@ module ActiveSupport
|
|
97
99
|
options = merged_options(options)
|
98
100
|
|
99
101
|
keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
|
102
|
+
|
100
103
|
raw_values = @data.get_multi(keys_to_names.keys)
|
101
104
|
values = {}
|
105
|
+
|
102
106
|
raw_values.each do |key, value|
|
103
107
|
entry = deserialize_entry(value)
|
104
|
-
|
108
|
+
|
109
|
+
unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
|
110
|
+
values[keys_to_names[key]] = entry.value
|
111
|
+
end
|
105
112
|
end
|
113
|
+
|
106
114
|
values
|
107
115
|
end
|
108
116
|
|
@@ -114,7 +122,7 @@ module ActiveSupport
|
|
114
122
|
options = merged_options(options)
|
115
123
|
instrument(:increment, name, amount: amount) do
|
116
124
|
rescue_error_with nil do
|
117
|
-
@data.incr(normalize_key(name, options), amount)
|
125
|
+
@data.incr(normalize_key(name, options), amount, options[:expires_in])
|
118
126
|
end
|
119
127
|
end
|
120
128
|
end
|
@@ -127,7 +135,7 @@ module ActiveSupport
|
|
127
135
|
options = merged_options(options)
|
128
136
|
instrument(:decrement, name, amount: amount) do
|
129
137
|
rescue_error_with nil do
|
130
|
-
@data.decr(normalize_key(name, options), amount)
|
138
|
+
@data.decr(normalize_key(name, options), amount, options[:expires_in])
|
131
139
|
end
|
132
140
|
end
|
133
141
|
end
|