activesupport 4.2.11.1 → 6.0.3.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 +4 -4
- data/CHANGELOG.md +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- 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/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -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/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,18 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
|
-
require
|
4
|
+
require "dalli"
|
3
5
|
rescue LoadError => e
|
4
6
|
$stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
|
5
7
|
raise e
|
6
8
|
end
|
7
9
|
|
8
|
-
require
|
9
|
-
require 'active_support/core_ext/marshal'
|
10
|
-
require 'active_support/core_ext/array/extract_options'
|
10
|
+
require "active_support/core_ext/array/extract_options"
|
11
11
|
|
12
12
|
module ActiveSupport
|
13
13
|
module Cache
|
14
14
|
# A cache store implementation which stores data in Memcached:
|
15
|
-
#
|
15
|
+
# https://memcached.org
|
16
16
|
#
|
17
17
|
# This is currently the most popular cache store for production websites.
|
18
18
|
#
|
@@ -24,13 +24,49 @@ module ActiveSupport
|
|
24
24
|
# MemCacheStore implements the Strategy::LocalCache strategy which implements
|
25
25
|
# an in-memory cache inside of a block.
|
26
26
|
class MemCacheStore < Store
|
27
|
+
# Provide support for raw values in the local cache strategy.
|
28
|
+
module LocalCacheWithRaw # :nodoc:
|
29
|
+
private
|
30
|
+
def write_entry(key, entry, **options)
|
31
|
+
if options[:raw] && local_cache
|
32
|
+
raw_entry = Entry.new(entry.value.to_s)
|
33
|
+
raw_entry.expires_at = entry.expires_at
|
34
|
+
super(key, raw_entry, **options)
|
35
|
+
else
|
36
|
+
super
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Advertise cache versioning support.
|
42
|
+
def self.supports_cache_versioning?
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
prepend Strategy::LocalCache
|
47
|
+
prepend LocalCacheWithRaw
|
48
|
+
|
27
49
|
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
|
28
50
|
|
29
|
-
|
51
|
+
# Creates a new Dalli::Client instance with specified addresses and options.
|
52
|
+
# By default address is equal localhost:11211.
|
53
|
+
#
|
54
|
+
# ActiveSupport::Cache::MemCacheStore.build_mem_cache
|
55
|
+
# # => #<Dalli::Client:0x007f98a47d2028 @servers=["localhost:11211"], @options={}, @ring=nil>
|
56
|
+
# ActiveSupport::Cache::MemCacheStore.build_mem_cache('localhost:10290')
|
57
|
+
# # => #<Dalli::Client:0x007f98a47b3a60 @servers=["localhost:10290"], @options={}, @ring=nil>
|
58
|
+
def self.build_mem_cache(*addresses) # :nodoc:
|
30
59
|
addresses = addresses.flatten
|
31
60
|
options = addresses.extract_options!
|
32
61
|
addresses = ["localhost:11211"] if addresses.empty?
|
33
|
-
|
62
|
+
pool_options = retrieve_pool_options(options)
|
63
|
+
|
64
|
+
if pool_options.empty?
|
65
|
+
Dalli::Client.new(addresses, options)
|
66
|
+
else
|
67
|
+
ensure_connection_pool_added!
|
68
|
+
ConnectionPool.new(pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) }
|
69
|
+
end
|
34
70
|
end
|
35
71
|
|
36
72
|
# Creates a new MemCacheStore object, with the given memcached server
|
@@ -53,82 +89,56 @@ module ActiveSupport
|
|
53
89
|
@data = addresses.first
|
54
90
|
else
|
55
91
|
mem_cache_options = options.dup
|
56
|
-
UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
|
92
|
+
UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
|
57
93
|
@data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
|
58
94
|
end
|
59
|
-
|
60
|
-
extend Strategy::LocalCache
|
61
|
-
extend LocalCacheWithRaw
|
62
|
-
end
|
63
|
-
|
64
|
-
# Reads multiple values from the cache using a single call to the
|
65
|
-
# servers for all keys. Options can be passed in the last argument.
|
66
|
-
def read_multi(*names)
|
67
|
-
options = names.extract_options!
|
68
|
-
options = merged_options(options)
|
69
|
-
keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
|
70
|
-
raw_values = @data.get_multi(keys_to_names.keys)
|
71
|
-
values = {}
|
72
|
-
raw_values.each do |key, value|
|
73
|
-
entry = deserialize_entry(value)
|
74
|
-
values[keys_to_names[key]] = entry.value unless entry.expired?
|
75
|
-
end
|
76
|
-
values
|
77
95
|
end
|
78
96
|
|
79
97
|
# Increment a cached value. This method uses the memcached incr atomic
|
80
98
|
# operator and can only be used on values written with the :raw option.
|
81
99
|
# Calling it on a value not stored with :raw will initialize that value
|
82
100
|
# to zero.
|
83
|
-
def increment(name, amount = 1, options = nil)
|
101
|
+
def increment(name, amount = 1, options = nil)
|
84
102
|
options = merged_options(options)
|
85
|
-
instrument(:increment, name, :
|
86
|
-
|
103
|
+
instrument(:increment, name, amount: amount) do
|
104
|
+
rescue_error_with nil do
|
105
|
+
@data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in]) }
|
106
|
+
end
|
87
107
|
end
|
88
|
-
rescue Dalli::DalliError => e
|
89
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
90
|
-
nil
|
91
108
|
end
|
92
109
|
|
93
110
|
# Decrement a cached value. This method uses the memcached decr atomic
|
94
111
|
# operator and can only be used on values written with the :raw option.
|
95
112
|
# Calling it on a value not stored with :raw will initialize that value
|
96
113
|
# to zero.
|
97
|
-
def decrement(name, amount = 1, options = nil)
|
114
|
+
def decrement(name, amount = 1, options = nil)
|
98
115
|
options = merged_options(options)
|
99
|
-
instrument(:decrement, name, :
|
100
|
-
|
116
|
+
instrument(:decrement, name, amount: amount) do
|
117
|
+
rescue_error_with nil do
|
118
|
+
@data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in]) }
|
119
|
+
end
|
101
120
|
end
|
102
|
-
rescue Dalli::DalliError => e
|
103
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
104
|
-
nil
|
105
121
|
end
|
106
122
|
|
107
123
|
# Clear the entire cache on all memcached servers. This method should
|
108
124
|
# be used with care when shared cache is being used.
|
109
125
|
def clear(options = nil)
|
110
|
-
@data.flush_all
|
111
|
-
rescue Dalli::DalliError => e
|
112
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
113
|
-
nil
|
126
|
+
rescue_error_with(nil) { @data.with { |c| c.flush_all } }
|
114
127
|
end
|
115
128
|
|
116
129
|
# Get the statistics from the memcached servers.
|
117
130
|
def stats
|
118
|
-
@data.stats
|
131
|
+
@data.with { |c| c.stats }
|
119
132
|
end
|
120
133
|
|
121
|
-
|
134
|
+
private
|
122
135
|
# Read an entry from the cache.
|
123
|
-
def read_entry(key, options)
|
124
|
-
deserialize_entry(@data.get(
|
125
|
-
rescue Dalli::DalliError => e
|
126
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
127
|
-
nil
|
136
|
+
def read_entry(key, **options)
|
137
|
+
rescue_error_with(nil) { deserialize_entry(@data.with { |c| c.get(key, options) }) }
|
128
138
|
end
|
129
139
|
|
130
140
|
# Write an entry to the cache.
|
131
|
-
def write_entry(key, entry, options)
|
141
|
+
def write_entry(key, entry, **options)
|
132
142
|
method = options && options[:unless_exist] ? :add : :set
|
133
143
|
value = options[:raw] ? entry.value.to_s : entry
|
134
144
|
expires_in = options[:expires_in].to_i
|
@@ -136,63 +146,57 @@ module ActiveSupport
|
|
136
146
|
# Set the memcache expire a few minutes in the future to support race condition ttls on read
|
137
147
|
expires_in += 5.minutes
|
138
148
|
end
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
false
|
149
|
+
rescue_error_with false do
|
150
|
+
@data.with { |c| c.send(method, key, value, expires_in, **options) }
|
151
|
+
end
|
143
152
|
end
|
144
153
|
|
145
|
-
#
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
154
|
+
# Reads multiple entries from the cache implementation.
|
155
|
+
def read_multi_entries(names, **options)
|
156
|
+
keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
|
157
|
+
|
158
|
+
raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) }
|
159
|
+
values = {}
|
160
|
+
|
161
|
+
raw_values.each do |key, value|
|
162
|
+
entry = deserialize_entry(value)
|
163
|
+
|
164
|
+
unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
|
165
|
+
values[keys_to_names[key]] = entry.value
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
values
|
151
170
|
end
|
152
171
|
|
153
|
-
|
172
|
+
# Delete an entry from the cache.
|
173
|
+
def delete_entry(key, **options)
|
174
|
+
rescue_error_with(false) { @data.with { |c| c.delete(key) } }
|
175
|
+
end
|
154
176
|
|
155
177
|
# Memcache keys are binaries. So we need to force their encoding to binary
|
156
178
|
# before applying the regular expression to ensure we are escaping all
|
157
179
|
# characters properly.
|
158
|
-
def
|
159
|
-
key =
|
180
|
+
def normalize_key(key, options)
|
181
|
+
key = super.dup
|
160
182
|
key = key.force_encoding(Encoding::ASCII_8BIT)
|
161
|
-
key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
|
162
|
-
key = "#{key[0, 213]}:md5:#{Digest
|
183
|
+
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
|
184
|
+
key = "#{key[0, 213]}:md5:#{ActiveSupport::Digest.hexdigest(key)}" if key.size > 250
|
163
185
|
key
|
164
186
|
end
|
165
187
|
|
166
|
-
def deserialize_entry(
|
167
|
-
if
|
168
|
-
entry = Marshal.load(raw_value) rescue raw_value
|
188
|
+
def deserialize_entry(entry)
|
189
|
+
if entry
|
169
190
|
entry.is_a?(Entry) ? entry : Entry.new(entry)
|
170
|
-
else
|
171
|
-
nil
|
172
191
|
end
|
173
192
|
end
|
174
193
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
entry = deserialize_entry(entry.value)
|
182
|
-
end
|
183
|
-
entry
|
184
|
-
end
|
185
|
-
|
186
|
-
def write_entry(key, entry, options) # :nodoc:
|
187
|
-
retval = super
|
188
|
-
if options[:raw] && local_cache && retval
|
189
|
-
raw_entry = Entry.new(entry.value.to_s)
|
190
|
-
raw_entry.expires_at = entry.expires_at
|
191
|
-
local_cache.write_entry(key, raw_entry, options)
|
192
|
-
end
|
193
|
-
retval
|
194
|
-
end
|
195
|
-
end
|
194
|
+
def rescue_error_with(fallback)
|
195
|
+
yield
|
196
|
+
rescue Dalli::DalliError => e
|
197
|
+
logger.error("DalliError (#{e}): #{e.message}") if logger
|
198
|
+
fallback
|
199
|
+
end
|
196
200
|
end
|
197
201
|
end
|
198
202
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "monitor"
|
2
4
|
|
3
5
|
module ActiveSupport
|
4
6
|
module Cache
|
5
7
|
# A cache store implementation which stores everything into memory in the
|
6
8
|
# same process. If you're running multiple Ruby on Rails server processes
|
7
|
-
# (which is the case if you're using
|
9
|
+
# (which is the case if you're using Phusion Passenger or puma clustered mode),
|
8
10
|
# then this means that Rails server process instances won't be able
|
9
11
|
# to share cache data with each other and this may not be the most
|
10
12
|
# appropriate cache in that scenario.
|
@@ -28,6 +30,12 @@ module ActiveSupport
|
|
28
30
|
@pruning = false
|
29
31
|
end
|
30
32
|
|
33
|
+
# Advertise cache versioning support.
|
34
|
+
def self.supports_cache_versioning?
|
35
|
+
true
|
36
|
+
end
|
37
|
+
|
38
|
+
# Delete all data stored in a given cache store.
|
31
39
|
def clear(options = nil)
|
32
40
|
synchronize do
|
33
41
|
@data.clear
|
@@ -39,11 +47,11 @@ module ActiveSupport
|
|
39
47
|
# Preemptively iterates through all stored keys and removes the ones which have expired.
|
40
48
|
def cleanup(options = nil)
|
41
49
|
options = merged_options(options)
|
42
|
-
instrument(:cleanup, :
|
43
|
-
keys = synchronize{ @data.keys }
|
50
|
+
instrument(:cleanup, size: @data.size) do
|
51
|
+
keys = synchronize { @data.keys }
|
44
52
|
keys.each do |key|
|
45
53
|
entry = @data[key]
|
46
|
-
delete_entry(key, options) if entry && entry.expired?
|
54
|
+
delete_entry(key, **options) if entry && entry.expired?
|
47
55
|
end
|
48
56
|
end
|
49
57
|
end
|
@@ -54,13 +62,13 @@ module ActiveSupport
|
|
54
62
|
return if pruning?
|
55
63
|
@pruning = true
|
56
64
|
begin
|
57
|
-
start_time =
|
65
|
+
start_time = Concurrent.monotonic_time
|
58
66
|
cleanup
|
59
|
-
instrument(:prune, target_size, :
|
60
|
-
keys = synchronize{ @key_access.keys.sort{|a,b| @key_access[a].to_f <=> @key_access[b].to_f} }
|
67
|
+
instrument(:prune, target_size, from: @cache_size) do
|
68
|
+
keys = synchronize { @key_access.keys.sort { |a, b| @key_access[a].to_f <=> @key_access[b].to_f } }
|
61
69
|
keys.each do |key|
|
62
|
-
delete_entry(key, options)
|
63
|
-
return if @cache_size <= target_size || (max_time &&
|
70
|
+
delete_entry(key, **options)
|
71
|
+
return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
|
64
72
|
end
|
65
73
|
end
|
66
74
|
ensure
|
@@ -75,39 +83,22 @@ module ActiveSupport
|
|
75
83
|
|
76
84
|
# Increment an integer value in the cache.
|
77
85
|
def increment(name, amount = 1, options = nil)
|
78
|
-
|
79
|
-
options = merged_options(options)
|
80
|
-
if num = read(name, options)
|
81
|
-
num = num.to_i + amount
|
82
|
-
write(name, num, options)
|
83
|
-
num
|
84
|
-
else
|
85
|
-
nil
|
86
|
-
end
|
87
|
-
end
|
86
|
+
modify_value(name, amount, options)
|
88
87
|
end
|
89
88
|
|
90
89
|
# Decrement an integer value in the cache.
|
91
90
|
def decrement(name, amount = 1, options = nil)
|
92
|
-
|
93
|
-
options = merged_options(options)
|
94
|
-
if num = read(name, options)
|
95
|
-
num = num.to_i - amount
|
96
|
-
write(name, num, options)
|
97
|
-
num
|
98
|
-
else
|
99
|
-
nil
|
100
|
-
end
|
101
|
-
end
|
91
|
+
modify_value(name, -amount, options)
|
102
92
|
end
|
103
93
|
|
94
|
+
# Deletes cache entries if the cache key matches a given pattern.
|
104
95
|
def delete_matched(matcher, options = nil)
|
105
96
|
options = merged_options(options)
|
106
97
|
instrument(:delete_matched, matcher.inspect) do
|
107
98
|
matcher = key_matcher(matcher, options)
|
108
99
|
keys = synchronize { @data.keys }
|
109
100
|
keys.each do |key|
|
110
|
-
delete_entry(key, options) if key.match(matcher)
|
101
|
+
delete_entry(key, **options) if key.match(matcher)
|
111
102
|
end
|
112
103
|
end
|
113
104
|
end
|
@@ -122,18 +113,19 @@ module ActiveSupport
|
|
122
113
|
@monitor.synchronize(&block)
|
123
114
|
end
|
124
115
|
|
125
|
-
|
126
|
-
|
116
|
+
private
|
127
117
|
PER_ENTRY_OVERHEAD = 240
|
128
118
|
|
129
119
|
def cached_size(key, entry)
|
130
120
|
key.to_s.bytesize + entry.size + PER_ENTRY_OVERHEAD
|
131
121
|
end
|
132
122
|
|
133
|
-
def read_entry(key, options)
|
123
|
+
def read_entry(key, **options)
|
134
124
|
entry = @data[key]
|
135
125
|
synchronize do
|
136
126
|
if entry
|
127
|
+
entry = entry.dup
|
128
|
+
entry.dup_value!
|
137
129
|
@key_access[key] = Time.now.to_f
|
138
130
|
else
|
139
131
|
@key_access.delete(key)
|
@@ -142,7 +134,7 @@ module ActiveSupport
|
|
142
134
|
entry
|
143
135
|
end
|
144
136
|
|
145
|
-
def write_entry(key, entry, options)
|
137
|
+
def write_entry(key, entry, **options)
|
146
138
|
entry.dup_value!
|
147
139
|
synchronize do
|
148
140
|
old_entry = @data[key]
|
@@ -159,7 +151,7 @@ module ActiveSupport
|
|
159
151
|
end
|
160
152
|
end
|
161
153
|
|
162
|
-
def delete_entry(key, options)
|
154
|
+
def delete_entry(key, **options)
|
163
155
|
synchronize do
|
164
156
|
@key_access.delete(key)
|
165
157
|
entry = @data.delete(key)
|
@@ -167,6 +159,17 @@ module ActiveSupport
|
|
167
159
|
!!entry
|
168
160
|
end
|
169
161
|
end
|
162
|
+
|
163
|
+
def modify_value(name, amount, options)
|
164
|
+
synchronize do
|
165
|
+
options = merged_options(options)
|
166
|
+
if num = read(name, options)
|
167
|
+
num = num.to_i + amount
|
168
|
+
write(name, num, options)
|
169
|
+
num
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
170
173
|
end
|
171
174
|
end
|
172
175
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport
|
2
4
|
module Cache
|
3
5
|
# A cache store implementation which doesn't actually store anything. Useful in
|
@@ -8,9 +10,11 @@ module ActiveSupport
|
|
8
10
|
# be cached inside blocks that utilize this strategy. See
|
9
11
|
# ActiveSupport::Cache::Strategy::LocalCache for more details.
|
10
12
|
class NullStore < Store
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
prepend Strategy::LocalCache
|
14
|
+
|
15
|
+
# Advertise cache versioning support.
|
16
|
+
def self.supports_cache_versioning?
|
17
|
+
true
|
14
18
|
end
|
15
19
|
|
16
20
|
def clear(options = nil)
|
@@ -28,15 +32,15 @@ module ActiveSupport
|
|
28
32
|
def delete_matched(matcher, options = nil)
|
29
33
|
end
|
30
34
|
|
31
|
-
|
32
|
-
def read_entry(key, options)
|
35
|
+
private
|
36
|
+
def read_entry(key, **options)
|
33
37
|
end
|
34
38
|
|
35
|
-
def write_entry(key, entry, options)
|
39
|
+
def write_entry(key, entry, **options)
|
36
40
|
true
|
37
41
|
end
|
38
42
|
|
39
|
-
def delete_entry(key, options)
|
43
|
+
def delete_entry(key, **options)
|
40
44
|
false
|
41
45
|
end
|
42
46
|
end
|