activesupport 1.2.4 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +505 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support/actionable_error.rb +50 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +50 -0
- data/lib/active_support/backtrace_cleaner.rb +234 -0
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +53 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +244 -0
- data/lib/active_support/cache/mem_cache_store.rb +288 -0
- data/lib/active_support/cache/memory_store.rb +264 -0
- data/lib/active_support/cache/null_store.rb +62 -0
- data/lib/active_support/cache/redis_cache_store.rb +498 -0
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +246 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +1170 -0
- data/lib/active_support/callbacks.rb +960 -0
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +79 -0
- data/lib/active_support/concern.rb +217 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +225 -0
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +193 -0
- data/lib/active_support/configuration_file.rb +60 -0
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/access.rb +100 -0
- data/lib/active_support/core_ext/array/conversions.rb +209 -26
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/array.rb +8 -4
- data/lib/active_support/core_ext/benchmark.rb +6 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/class/attribute.rb +137 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +24 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +18 -0
- data/lib/active_support/core_ext/date/calculations.rb +161 -0
- data/lib/active_support/core_ext/date/conversions.rb +95 -28
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +18 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/digest/uuid.rb +76 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +277 -7
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/file/atomic.rb +72 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/hash/conversions.rb +262 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
- data/lib/active_support/core_ext/hash/keys.rb +134 -44
- data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
- data/lib/active_support/core_ext/hash/slice.rb +27 -0
- data/lib/active_support/core_ext/hash.rb +9 -8
- data/lib/active_support/core_ext/integer/inflections.rb +29 -13
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/integer.rb +4 -6
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/kernel.rb +4 -78
- data/lib/active_support/core_ext/load_error.rb +6 -35
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +225 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +65 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/name_error.rb +59 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/time.rb +64 -57
- data/lib/active_support/core_ext/numeric.rb +4 -6
- data/lib/active_support/core_ext/object/acts_like.rb +45 -0
- data/lib/active_support/core_ext/object/blank.rb +199 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
- data/lib/active_support/core_ext/object/duplicable.rb +69 -0
- data/lib/active_support/core_ext/object/inclusion.rb +37 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
- data/lib/active_support/core_ext/object/json.rb +267 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +93 -0
- data/lib/active_support/core_ext/object/try.rb +158 -0
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +101 -0
- data/lib/active_support/core_ext/object.rb +17 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +58 -17
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +5 -4
- data/lib/active_support/core_ext/regexp.rb +14 -0
- data/lib/active_support/core_ext/securerandom.rb +57 -0
- data/lib/active_support/core_ext/string/access.rb +93 -56
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +57 -16
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +151 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +297 -54
- data/lib/active_support/core_ext/string/inquiry.rb +16 -0
- data/lib/active_support/core_ext/string/multibyte.rb +67 -0
- data/lib/active_support/core_ext/string/output_safety.rb +235 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/string.rb +14 -10
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/thread/backtrace/location.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +358 -153
- data/lib/active_support/core_ext/time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/time/conversions.rb +69 -30
- data/lib/active_support/core_ext/time/zones.rb +97 -0
- data/lib/active_support/core_ext/time.rb +6 -6
- data/lib/active_support/core_ext.rb +5 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +243 -0
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +183 -0
- data/lib/active_support/dependencies/autoload.rb +72 -0
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +84 -222
- data/lib/active_support/deprecation/behaviors.rb +148 -0
- data/lib/active_support/deprecation/constant_accessor.rb +74 -0
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/method_wrappers.rb +68 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
- data/lib/active_support/deprecation/reporting.rb +162 -0
- data/lib/active_support/deprecation.rb +81 -0
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +112 -0
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +64 -0
- data/lib/active_support/duration.rb +524 -0
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +126 -0
- data/lib/active_support/encrypted_file.rb +133 -0
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +318 -0
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +185 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +110 -0
- data/lib/active_support/execution_wrapper.rb +150 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +166 -0
- data/lib/active_support/fork_tracker.rb +43 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +41 -0
- data/lib/active_support/hash_with_indifferent_access.rb +464 -0
- data/lib/active_support/html_safe_translation.rb +56 -0
- data/lib/active_support/i18n.rb +17 -0
- data/lib/active_support/i18n_railtie.rb +140 -0
- data/lib/active_support/inflections.rb +68 -49
- data/lib/active_support/inflector/inflections.rb +290 -0
- data/lib/active_support/inflector/methods.rb +387 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/inflector.rb +7 -164
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +78 -0
- data/lib/active_support/json/encoding.rb +256 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/key_generator.rb +66 -0
- data/lib/active_support/lazy_load_hooks.rb +107 -0
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +141 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/log_subscriber.rb +188 -0
- data/lib/active_support/logger.rb +55 -0
- data/lib/active_support/logger_silence.rb +21 -0
- data/lib/active_support/logger_thread_safe_level.rb +50 -0
- data/lib/active_support/message_encryptor.rb +374 -0
- data/lib/active_support/message_encryptors.rb +193 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +310 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +377 -0
- data/lib/active_support/message_verifiers.rb +189 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +146 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotation_coordinator.rb +102 -0
- data/lib/active_support/messages/rotator.rb +69 -0
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +188 -0
- data/lib/active_support/multibyte/unicode.rb +42 -0
- data/lib/active_support/multibyte.rb +27 -0
- data/lib/active_support/notifications/fanout.rb +467 -0
- data/lib/active_support/notifications/instrumenter.rb +240 -0
- data/lib/active_support/notifications.rb +281 -0
- data/lib/active_support/number_helper/number_converter.rb +190 -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 +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +479 -0
- data/lib/active_support/option_merger.rb +38 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +141 -25
- data/lib/active_support/parameter_filter.rb +157 -0
- data/lib/active_support/rails.rb +26 -0
- data/lib/active_support/railtie.rb +180 -0
- data/lib/active_support/reloader.rb +138 -0
- data/lib/active_support/rescuable.rb +176 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +35 -0
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +141 -0
- data/lib/active_support/syntax_error_proxy.rb +67 -0
- data/lib/active_support/tagged_logging.rb +157 -0
- data/lib/active_support/test_case.rb +365 -0
- data/lib/active_support/testing/assertions.rb +369 -0
- data/lib/active_support/testing/autorun.rb +10 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +82 -0
- data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +121 -0
- data/lib/active_support/testing/method_call_assertions.rb +69 -0
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +98 -0
- data/lib/active_support/testing/parallelization/worker.rb +107 -0
- data/lib/active_support/testing/parallelization.rb +79 -0
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +57 -0
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +273 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +613 -0
- data/lib/active_support/values/time_zone.rb +599 -158
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +175 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +137 -0
- data/lib/active_support/xml_mini.rb +212 -0
- data/lib/active_support.rb +122 -10
- metadata +524 -93
- data/CHANGELOG +0 -283
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -523
- data/lib/active_support/class_attribute_accessors.rb +0 -57
- data/lib/active_support/class_inheritable_attributes.rb +0 -117
- data/lib/active_support/clean_logger.rb +0 -36
- data/lib/active_support/core_ext/blank.rb +0 -38
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
- data/lib/active_support/core_ext/cgi.rb +0 -5
- data/lib/active_support/core_ext/exception.rb +0 -29
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
- data/lib/active_support/core_ext/object_and_class.rb +0 -44
- data/lib/active_support/module_attribute_accessors.rb +0 -57
- data/lib/active_support/whiny_nil.rb +0 -38
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require "dalli"
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
warn "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
|
|
7
|
+
raise e
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
require "connection_pool"
|
|
11
|
+
require "delegate"
|
|
12
|
+
require "active_support/core_ext/enumerable"
|
|
13
|
+
require "active_support/core_ext/array/extract_options"
|
|
14
|
+
require "active_support/core_ext/numeric/time"
|
|
15
|
+
|
|
16
|
+
module ActiveSupport
|
|
17
|
+
module Cache
|
|
18
|
+
# = Memcached \Cache \Store
|
|
19
|
+
#
|
|
20
|
+
# A cache store implementation which stores data in Memcached:
|
|
21
|
+
# https://memcached.org
|
|
22
|
+
#
|
|
23
|
+
# This is currently the most popular cache store for production websites.
|
|
24
|
+
#
|
|
25
|
+
# Special features:
|
|
26
|
+
# - Clustering and load balancing. One can specify multiple memcached servers,
|
|
27
|
+
# and +MemCacheStore+ will load balance between all available servers. If a
|
|
28
|
+
# server goes down, then +MemCacheStore+ will ignore it until it comes back up.
|
|
29
|
+
#
|
|
30
|
+
# +MemCacheStore+ implements the Strategy::LocalCache strategy which
|
|
31
|
+
# implements an in-memory cache inside of a block.
|
|
32
|
+
class MemCacheStore < Store
|
|
33
|
+
# These options represent behavior overridden by this implementation and should
|
|
34
|
+
# not be allowed to get down to the Dalli client
|
|
35
|
+
OVERRIDDEN_OPTIONS = UNIVERSAL_OPTIONS
|
|
36
|
+
|
|
37
|
+
# Advertise cache versioning support.
|
|
38
|
+
def self.supports_cache_versioning?
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
prepend Strategy::LocalCache
|
|
43
|
+
|
|
44
|
+
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
|
|
45
|
+
|
|
46
|
+
# Creates a new Dalli::Client instance with specified addresses and options.
|
|
47
|
+
# If no addresses are provided, we give nil to Dalli::Client, so it uses its fallbacks:
|
|
48
|
+
# - ENV["MEMCACHE_SERVERS"] (if defined)
|
|
49
|
+
# - "127.0.0.1:11211" (otherwise)
|
|
50
|
+
#
|
|
51
|
+
# ActiveSupport::Cache::MemCacheStore.build_mem_cache
|
|
52
|
+
# # => #<Dalli::Client:0x007f98a47d2028 @servers=["127.0.0.1:11211"], @options={}, @ring=nil>
|
|
53
|
+
# ActiveSupport::Cache::MemCacheStore.build_mem_cache('localhost:10290')
|
|
54
|
+
# # => #<Dalli::Client:0x007f98a47b3a60 @servers=["localhost:10290"], @options={}, @ring=nil>
|
|
55
|
+
def self.build_mem_cache(*addresses) # :nodoc:
|
|
56
|
+
addresses = addresses.flatten
|
|
57
|
+
options = addresses.extract_options!
|
|
58
|
+
addresses = nil if addresses.compact.empty?
|
|
59
|
+
pool_options = retrieve_pool_options(options)
|
|
60
|
+
|
|
61
|
+
if pool_options
|
|
62
|
+
ConnectionPool.new(**pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) }
|
|
63
|
+
else
|
|
64
|
+
Dalli::Client.new(addresses, options)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Creates a new +MemCacheStore+ object, with the given memcached server
|
|
69
|
+
# addresses. Each address is either a host name, or a host-with-port string
|
|
70
|
+
# in the form of "host_name:port". For example:
|
|
71
|
+
#
|
|
72
|
+
# ActiveSupport::Cache::MemCacheStore.new("localhost", "server-downstairs.localnetwork:8229")
|
|
73
|
+
#
|
|
74
|
+
# If no addresses are provided, but <tt>ENV['MEMCACHE_SERVERS']</tt> is defined, it will be used instead. Otherwise,
|
|
75
|
+
# +MemCacheStore+ will connect to localhost:11211 (the default memcached port).
|
|
76
|
+
def initialize(*addresses)
|
|
77
|
+
addresses = addresses.flatten
|
|
78
|
+
options = addresses.extract_options!
|
|
79
|
+
if options.key?(:cache_nils)
|
|
80
|
+
options[:skip_nil] = !options.delete(:cache_nils)
|
|
81
|
+
end
|
|
82
|
+
options[:max_key_size] ||= MAX_KEY_SIZE
|
|
83
|
+
super(options)
|
|
84
|
+
|
|
85
|
+
unless [String, Dalli::Client, NilClass].include?(addresses.first.class)
|
|
86
|
+
raise ArgumentError, "First argument must be an empty array, address, or array of addresses."
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
@mem_cache_options = options.dup
|
|
90
|
+
# The value "compress: false" prevents duplicate compression within Dalli.
|
|
91
|
+
@mem_cache_options[:compress] = false
|
|
92
|
+
(OVERRIDDEN_OPTIONS - %i(compress)).each { |name| @mem_cache_options.delete(name) }
|
|
93
|
+
@data = self.class.build_mem_cache(*(addresses + [@mem_cache_options]))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def inspect
|
|
97
|
+
instance = @data || @mem_cache_options
|
|
98
|
+
"#<#{self.class} options=#{options.inspect} mem_cache=#{instance.inspect}>"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# :method: write
|
|
103
|
+
# :call-seq: write(name, value, options = nil)
|
|
104
|
+
#
|
|
105
|
+
# Behaves the same as ActiveSupport::Cache::Store#write, but supports
|
|
106
|
+
# additional options specific to memcached.
|
|
107
|
+
#
|
|
108
|
+
# ==== Additional Options
|
|
109
|
+
#
|
|
110
|
+
# * <tt>raw: true</tt> - Sends the value directly to the server as raw
|
|
111
|
+
# bytes. The value must be a string or number. You can use memcached
|
|
112
|
+
# direct operations like +increment+ and +decrement+ only on raw values.
|
|
113
|
+
|
|
114
|
+
# Increment a cached integer value using the memcached incr atomic operator.
|
|
115
|
+
# Returns the updated value.
|
|
116
|
+
#
|
|
117
|
+
# If the key is unset or has expired, it will be set to +amount+:
|
|
118
|
+
#
|
|
119
|
+
# cache.increment("foo") # => 1
|
|
120
|
+
# cache.increment("bar", 100) # => 100
|
|
121
|
+
#
|
|
122
|
+
# To set a specific value, call #write passing <tt>raw: true</tt>:
|
|
123
|
+
#
|
|
124
|
+
# cache.write("baz", 5, raw: true)
|
|
125
|
+
# cache.increment("baz") # => 6
|
|
126
|
+
#
|
|
127
|
+
# Incrementing a non-numeric value, or a value written without
|
|
128
|
+
# <tt>raw: true</tt>, will fail and return +nil+.
|
|
129
|
+
#
|
|
130
|
+
# To read the value later, call #read_counter:
|
|
131
|
+
#
|
|
132
|
+
# cache.increment("baz") # => 7
|
|
133
|
+
# cache.read_counter("baz") # 7
|
|
134
|
+
def increment(name, amount = 1, options = nil)
|
|
135
|
+
options = merged_options(options)
|
|
136
|
+
key = normalize_key(name, options)
|
|
137
|
+
|
|
138
|
+
instrument(:increment, key, amount: amount) do
|
|
139
|
+
rescue_error_with nil do
|
|
140
|
+
@data.with { |c| c.incr(key, amount, options[:expires_in], amount) }
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Decrement a cached integer value using the memcached decr atomic operator.
|
|
146
|
+
# Returns the updated value.
|
|
147
|
+
#
|
|
148
|
+
# If the key is unset or has expired, it will be set to 0. Memcached
|
|
149
|
+
# does not support negative counters.
|
|
150
|
+
#
|
|
151
|
+
# cache.decrement("foo") # => 0
|
|
152
|
+
#
|
|
153
|
+
# To set a specific value, call #write passing <tt>raw: true</tt>:
|
|
154
|
+
#
|
|
155
|
+
# cache.write("baz", 5, raw: true)
|
|
156
|
+
# cache.decrement("baz") # => 4
|
|
157
|
+
#
|
|
158
|
+
# Decrementing a non-numeric value, or a value written without
|
|
159
|
+
# <tt>raw: true</tt>, will fail and return +nil+.
|
|
160
|
+
#
|
|
161
|
+
# To read the value later, call #read_counter:
|
|
162
|
+
#
|
|
163
|
+
# cache.decrement("baz") # => 3
|
|
164
|
+
# cache.read_counter("baz") # 3
|
|
165
|
+
def decrement(name, amount = 1, options = nil)
|
|
166
|
+
options = merged_options(options)
|
|
167
|
+
key = normalize_key(name, options)
|
|
168
|
+
|
|
169
|
+
instrument(:decrement, key, amount: amount) do
|
|
170
|
+
rescue_error_with nil do
|
|
171
|
+
@data.with { |c| c.decr(key, amount, options[:expires_in], 0) }
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Clear the entire cache on all memcached servers. This method should
|
|
177
|
+
# be used with care when shared cache is being used.
|
|
178
|
+
def clear(options = nil)
|
|
179
|
+
rescue_error_with(nil) { @data.with { |c| c.flush_all } }
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Get the statistics from the memcached servers.
|
|
183
|
+
def stats
|
|
184
|
+
@data.with { |c| c.stats }
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
private
|
|
188
|
+
# Read an entry from the cache.
|
|
189
|
+
def read_entry(key, **options)
|
|
190
|
+
deserialize_entry(read_serialized_entry(key, **options), **options)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def read_serialized_entry(key, **options)
|
|
194
|
+
rescue_error_with(nil) do
|
|
195
|
+
@data.with { |c| c.get(key, options) }
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Write an entry to the cache.
|
|
200
|
+
def write_entry(key, entry, **options)
|
|
201
|
+
write_serialized_entry(key, serialize_entry(entry, **options), **options)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def write_serialized_entry(key, payload, **options)
|
|
205
|
+
method = options[:unless_exist] ? :add : :set
|
|
206
|
+
expires_in = options[:expires_in].to_i
|
|
207
|
+
if options[:race_condition_ttl] && expires_in > 0 && !options[:raw]
|
|
208
|
+
# Set the memcache expire a few minutes in the future to support race condition ttls on read
|
|
209
|
+
expires_in += 5.minutes
|
|
210
|
+
end
|
|
211
|
+
rescue_error_with nil do
|
|
212
|
+
# Don't pass compress option to Dalli since we are already dealing with compression.
|
|
213
|
+
options.delete(:compress)
|
|
214
|
+
@data.with { |c| !!c.send(method, key, payload, expires_in, **options) }
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Reads multiple entries from the cache implementation.
|
|
219
|
+
def read_multi_entries(names, **options)
|
|
220
|
+
keys_to_names = names.index_by { |name| normalize_key(name, options) }
|
|
221
|
+
|
|
222
|
+
rescue_error_with({}) do
|
|
223
|
+
raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) }
|
|
224
|
+
|
|
225
|
+
values = {}
|
|
226
|
+
|
|
227
|
+
raw_values.each do |key, value|
|
|
228
|
+
entry = deserialize_entry(value, raw: options[:raw])
|
|
229
|
+
|
|
230
|
+
unless entry.nil? || entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
|
|
231
|
+
begin
|
|
232
|
+
values[keys_to_names[key]] = entry.value
|
|
233
|
+
rescue DeserializationError
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
values
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Delete an entry from the cache.
|
|
243
|
+
def delete_entry(key, **options)
|
|
244
|
+
rescue_error_with(false) { @data.with { |c| c.delete(key) } }
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def serialize_entry(entry, raw: false, **options)
|
|
248
|
+
if raw
|
|
249
|
+
entry.value.to_s
|
|
250
|
+
else
|
|
251
|
+
super(entry, raw: raw, **options)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Memcache keys are binaries. So we need to force their encoding to binary
|
|
256
|
+
# before applying the regular expression to ensure we are escaping all
|
|
257
|
+
# characters properly.
|
|
258
|
+
def normalize_key(key, options)
|
|
259
|
+
key = expand_and_namespace_key(key, options)
|
|
260
|
+
if key
|
|
261
|
+
key = key.dup.force_encoding(Encoding::ASCII_8BIT)
|
|
262
|
+
key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
|
|
263
|
+
end
|
|
264
|
+
truncate_key(key)
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def deserialize_entry(payload, raw: false, **)
|
|
268
|
+
if payload && raw
|
|
269
|
+
Entry.new(payload)
|
|
270
|
+
else
|
|
271
|
+
super(payload)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def rescue_error_with(fallback)
|
|
276
|
+
yield
|
|
277
|
+
rescue Dalli::DalliError, ConnectionPool::Error, ConnectionPool::TimeoutError => error
|
|
278
|
+
logger.error("DalliError (#{error}): #{error.message}") if logger
|
|
279
|
+
ActiveSupport.error_reporter&.report(
|
|
280
|
+
error,
|
|
281
|
+
severity: :warning,
|
|
282
|
+
source: "mem_cache_store.active_support",
|
|
283
|
+
)
|
|
284
|
+
fallback
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "monitor"
|
|
4
|
+
|
|
5
|
+
module ActiveSupport
|
|
6
|
+
module Cache
|
|
7
|
+
# = Memory \Cache \Store
|
|
8
|
+
#
|
|
9
|
+
# A cache store implementation which stores everything into memory in the
|
|
10
|
+
# same process. If you're running multiple Ruby on \Rails server processes
|
|
11
|
+
# (which is the case if you're using Phusion Passenger or puma clustered mode),
|
|
12
|
+
# then this means that \Rails server process instances won't be able
|
|
13
|
+
# to share cache data with each other and this may not be the most
|
|
14
|
+
# appropriate cache in that scenario.
|
|
15
|
+
#
|
|
16
|
+
# This cache has a bounded size specified by the +:size+ options to the
|
|
17
|
+
# initializer (default is 32Mb). When the cache exceeds the allotted size,
|
|
18
|
+
# a cleanup will occur which tries to prune the cache down to three quarters
|
|
19
|
+
# of the maximum size by removing the least recently used entries.
|
|
20
|
+
#
|
|
21
|
+
# Unlike other Cache store implementations, +MemoryStore+ does not compress
|
|
22
|
+
# values by default. +MemoryStore+ does not benefit from compression as much
|
|
23
|
+
# as other Store implementations, as it does not send data over a network.
|
|
24
|
+
# However, when compression is enabled, it still pays the full cost of
|
|
25
|
+
# compression in terms of cpu use.
|
|
26
|
+
#
|
|
27
|
+
# +MemoryStore+ is thread-safe.
|
|
28
|
+
class MemoryStore < Store
|
|
29
|
+
prepend Strategy::LocalCache
|
|
30
|
+
|
|
31
|
+
module DupCoder # :nodoc:
|
|
32
|
+
extend self
|
|
33
|
+
|
|
34
|
+
def dump(entry)
|
|
35
|
+
if entry.value && entry.value != true && !entry.value.is_a?(Numeric)
|
|
36
|
+
Cache::Entry.new(dump_value(entry.value), expires_at: entry.expires_at, version: entry.version)
|
|
37
|
+
else
|
|
38
|
+
entry
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def dump_compressed(entry, threshold)
|
|
43
|
+
compressed_entry = entry.compressed(threshold)
|
|
44
|
+
compressed_entry.compressed? ? compressed_entry : dump(entry)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load(entry)
|
|
48
|
+
if !entry.compressed? && entry.value.is_a?(String)
|
|
49
|
+
Cache::Entry.new(load_value(entry.value), expires_at: entry.expires_at, version: entry.version)
|
|
50
|
+
else
|
|
51
|
+
entry
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
MARSHAL_SIGNATURE = "\x04\x08".b.freeze
|
|
57
|
+
|
|
58
|
+
def dump_value(value)
|
|
59
|
+
if value.is_a?(String) && !value.start_with?(MARSHAL_SIGNATURE)
|
|
60
|
+
value.dup
|
|
61
|
+
else
|
|
62
|
+
Marshal.dump(value)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def load_value(string)
|
|
67
|
+
if string.start_with?(MARSHAL_SIGNATURE)
|
|
68
|
+
Marshal.load(string)
|
|
69
|
+
else
|
|
70
|
+
string.dup
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def initialize(options = nil)
|
|
76
|
+
options ||= {}
|
|
77
|
+
options[:coder] = DupCoder unless options.key?(:coder) || options.key?(:serializer)
|
|
78
|
+
# Disable compression by default.
|
|
79
|
+
options[:compress] ||= false
|
|
80
|
+
super(options)
|
|
81
|
+
@data = {}
|
|
82
|
+
@max_size = options[:size] || 32.megabytes
|
|
83
|
+
@max_prune_time = options[:max_prune_time] || 2
|
|
84
|
+
@cache_size = 0
|
|
85
|
+
@monitor = Monitor.new
|
|
86
|
+
@pruning = false
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Advertise cache versioning support.
|
|
90
|
+
def self.supports_cache_versioning?
|
|
91
|
+
true
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Delete all data stored in a given cache store.
|
|
95
|
+
def clear(options = nil)
|
|
96
|
+
synchronize do
|
|
97
|
+
@data.clear
|
|
98
|
+
@cache_size = 0
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Preemptively iterates through all stored keys and removes the ones which have expired.
|
|
103
|
+
def cleanup(options = nil)
|
|
104
|
+
options = merged_options(options)
|
|
105
|
+
_instrument(:cleanup, size: @data.size) do
|
|
106
|
+
keys = synchronize { @data.keys }
|
|
107
|
+
keys.each do |key|
|
|
108
|
+
entry = @data[key]
|
|
109
|
+
delete_entry(key, **options) if entry && entry.expired?
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# To ensure entries fit within the specified memory prune the cache by removing the least
|
|
115
|
+
# recently accessed entries.
|
|
116
|
+
def prune(target_size, max_time = nil)
|
|
117
|
+
return if pruning?
|
|
118
|
+
@pruning = true
|
|
119
|
+
begin
|
|
120
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
121
|
+
cleanup
|
|
122
|
+
instrument(:prune, target_size, from: @cache_size) do
|
|
123
|
+
keys = synchronize { @data.keys }
|
|
124
|
+
keys.each do |key|
|
|
125
|
+
delete_entry(key, **options)
|
|
126
|
+
return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
ensure
|
|
130
|
+
@pruning = false
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Returns true if the cache is currently being pruned.
|
|
135
|
+
def pruning?
|
|
136
|
+
@pruning
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Increment a cached integer value. Returns the updated value.
|
|
140
|
+
#
|
|
141
|
+
# If the key is unset, it will be set to +amount+:
|
|
142
|
+
#
|
|
143
|
+
# cache.increment("foo") # => 1
|
|
144
|
+
# cache.increment("bar", 100) # => 100
|
|
145
|
+
#
|
|
146
|
+
# To set a specific value, call #write:
|
|
147
|
+
#
|
|
148
|
+
# cache.write("baz", 5)
|
|
149
|
+
# cache.increment("baz") # => 6
|
|
150
|
+
#
|
|
151
|
+
def increment(name, amount = 1, **options)
|
|
152
|
+
instrument(:increment, name, amount: amount) do
|
|
153
|
+
modify_value(name, amount, **options)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Decrement a cached integer value. Returns the updated value.
|
|
158
|
+
#
|
|
159
|
+
# If the key is unset or has expired, it will be set to +-amount+.
|
|
160
|
+
#
|
|
161
|
+
# cache.decrement("foo") # => -1
|
|
162
|
+
#
|
|
163
|
+
# To set a specific value, call #write:
|
|
164
|
+
#
|
|
165
|
+
# cache.write("baz", 5)
|
|
166
|
+
# cache.decrement("baz") # => 4
|
|
167
|
+
#
|
|
168
|
+
def decrement(name, amount = 1, **options)
|
|
169
|
+
instrument(:decrement, name, amount: amount) do
|
|
170
|
+
modify_value(name, -amount, **options)
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Deletes cache entries if the cache key matches a given pattern.
|
|
175
|
+
def delete_matched(matcher, options = nil)
|
|
176
|
+
options = merged_options(options)
|
|
177
|
+
matcher = key_matcher(matcher, options)
|
|
178
|
+
|
|
179
|
+
instrument(:delete_matched, matcher.inspect) do
|
|
180
|
+
keys = synchronize { @data.keys }
|
|
181
|
+
keys.each do |key|
|
|
182
|
+
delete_entry(key, **options) if key.match(matcher)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def inspect # :nodoc:
|
|
188
|
+
"#<#{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Synchronize calls to the cache. This should be called wherever the underlying cache implementation
|
|
192
|
+
# is not thread safe.
|
|
193
|
+
def synchronize(&block) # :nodoc:
|
|
194
|
+
@monitor.synchronize(&block)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
private
|
|
198
|
+
PER_ENTRY_OVERHEAD = 240
|
|
199
|
+
|
|
200
|
+
def cached_size(key, payload)
|
|
201
|
+
key.to_s.bytesize + payload.bytesize + PER_ENTRY_OVERHEAD
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def read_entry(key, **options)
|
|
205
|
+
entry = nil
|
|
206
|
+
synchronize do
|
|
207
|
+
payload = @data.delete(key)
|
|
208
|
+
if payload
|
|
209
|
+
@data[key] = payload
|
|
210
|
+
entry = deserialize_entry(payload)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
entry
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def write_entry(key, entry, **options)
|
|
217
|
+
payload = serialize_entry(entry, **options)
|
|
218
|
+
synchronize do
|
|
219
|
+
return false if options[:unless_exist] && exist?(key, namespace: nil)
|
|
220
|
+
|
|
221
|
+
old_payload = @data[key]
|
|
222
|
+
if old_payload
|
|
223
|
+
@cache_size -= (old_payload.bytesize - payload.bytesize)
|
|
224
|
+
else
|
|
225
|
+
@cache_size += cached_size(key, payload)
|
|
226
|
+
end
|
|
227
|
+
@data[key] = payload
|
|
228
|
+
prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size
|
|
229
|
+
true
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
def delete_entry(key, **options)
|
|
234
|
+
synchronize do
|
|
235
|
+
payload = @data.delete(key)
|
|
236
|
+
@cache_size -= cached_size(key, payload) if payload
|
|
237
|
+
!!payload
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Modifies the amount of an integer value that is stored in the cache.
|
|
242
|
+
# If the key is not found it is created and set to +amount+.
|
|
243
|
+
def modify_value(name, amount, **options)
|
|
244
|
+
options = merged_options(options)
|
|
245
|
+
key = normalize_key(name, options)
|
|
246
|
+
version = normalize_version(name, options)
|
|
247
|
+
|
|
248
|
+
synchronize do
|
|
249
|
+
entry = read_entry(key, **options)
|
|
250
|
+
|
|
251
|
+
if !entry || entry.expired? || entry.mismatched?(version)
|
|
252
|
+
write(name, Integer(amount), options)
|
|
253
|
+
amount
|
|
254
|
+
else
|
|
255
|
+
num = entry.value.to_i + amount
|
|
256
|
+
entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
|
|
257
|
+
write_entry(key, entry)
|
|
258
|
+
num
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveSupport
|
|
4
|
+
module Cache
|
|
5
|
+
# = Null \Cache \Store
|
|
6
|
+
#
|
|
7
|
+
# A cache store implementation which doesn't actually store anything. Useful in
|
|
8
|
+
# development and test environments where you don't want caching turned on but
|
|
9
|
+
# need to go through the caching interface.
|
|
10
|
+
#
|
|
11
|
+
# This cache does implement the local cache strategy, so values will actually
|
|
12
|
+
# be cached inside blocks that utilize this strategy. See
|
|
13
|
+
# ActiveSupport::Cache::Strategy::LocalCache for more details.
|
|
14
|
+
class NullStore < Store
|
|
15
|
+
prepend Strategy::LocalCache
|
|
16
|
+
|
|
17
|
+
# Advertise cache versioning support.
|
|
18
|
+
def self.supports_cache_versioning?
|
|
19
|
+
true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def clear(options = nil)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def cleanup(options = nil)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def increment(name, amount = 1, **options)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def decrement(name, amount = 1, **options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def delete_matched(matcher, options = nil)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def inspect # :nodoc:
|
|
38
|
+
"#<#{self.class.name} options=#{@options.inspect}>"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
def read_entry(key, **s)
|
|
43
|
+
deserialize_entry(read_serialized_entry(key))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def read_serialized_entry(_key, **)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def write_entry(key, entry, **)
|
|
50
|
+
write_serialized_entry(key, serialize_entry(entry))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def write_serialized_entry(_key, _payload, **)
|
|
54
|
+
true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def delete_entry(key, **options)
|
|
58
|
+
false
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|