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