activesupport 6.0.6.1 → 7.1.3.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.
Files changed (245) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +865 -438
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -6
  5. data/lib/active_support/actionable_error.rb +4 -2
  6. data/lib/active_support/array_inquirer.rb +4 -2
  7. data/lib/active_support/backtrace_cleaner.rb +30 -10
  8. data/lib/active_support/benchmarkable.rb +4 -3
  9. data/lib/active_support/broadcast_logger.rb +250 -0
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache/coder.rb +153 -0
  12. data/lib/active_support/cache/entry.rb +134 -0
  13. data/lib/active_support/cache/file_store.rb +53 -20
  14. data/lib/active_support/cache/mem_cache_store.rb +208 -63
  15. data/lib/active_support/cache/memory_store.rb +120 -38
  16. data/lib/active_support/cache/null_store.rb +16 -2
  17. data/lib/active_support/cache/redis_cache_store.rb +201 -208
  18. data/lib/active_support/cache/serializer_with_fallback.rb +175 -0
  19. data/lib/active_support/cache/strategy/local_cache.rb +73 -66
  20. data/lib/active_support/cache.rb +539 -261
  21. data/lib/active_support/callbacks.rb +273 -142
  22. data/lib/active_support/code_generator.rb +65 -0
  23. data/lib/active_support/concern.rb +53 -7
  24. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +44 -7
  25. data/lib/active_support/concurrency/null_lock.rb +13 -0
  26. data/lib/active_support/concurrency/share_lock.rb +2 -2
  27. data/lib/active_support/configurable.rb +19 -6
  28. data/lib/active_support/configuration_file.rb +51 -0
  29. data/lib/active_support/core_ext/array/access.rb +1 -5
  30. data/lib/active_support/core_ext/array/conversions.rb +15 -13
  31. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  32. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  33. data/lib/active_support/core_ext/benchmark.rb +2 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  35. data/lib/active_support/core_ext/class/attribute.rb +34 -44
  36. data/lib/active_support/core_ext/class/subclasses.rb +19 -29
  37. data/lib/active_support/core_ext/date/blank.rb +1 -1
  38. data/lib/active_support/core_ext/date/calculations.rb +24 -9
  39. data/lib/active_support/core_ext/date/conversions.rb +18 -16
  40. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -4
  41. data/lib/active_support/core_ext/date_and_time/compatibility.rb +15 -0
  42. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  43. data/lib/active_support/core_ext/date_time/calculations.rb +4 -0
  44. data/lib/active_support/core_ext/date_time/conversions.rb +19 -15
  45. data/lib/active_support/core_ext/digest/uuid.rb +30 -13
  46. data/lib/active_support/core_ext/enumerable.rb +146 -72
  47. data/lib/active_support/core_ext/erb/util.rb +196 -0
  48. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  49. data/lib/active_support/core_ext/hash/conversions.rb +3 -4
  50. data/lib/active_support/core_ext/hash/deep_merge.rb +22 -14
  51. data/lib/active_support/core_ext/hash/deep_transform_values.rb +4 -4
  52. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  53. data/lib/active_support/core_ext/hash/keys.rb +5 -5
  54. data/lib/active_support/core_ext/hash/slice.rb +3 -2
  55. data/lib/active_support/core_ext/integer/inflections.rb +12 -12
  56. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  58. data/lib/active_support/core_ext/load_error.rb +1 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -2
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +31 -29
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +51 -20
  62. data/lib/active_support/core_ext/module/concerning.rb +14 -8
  63. data/lib/active_support/core_ext/module/delegation.rb +75 -42
  64. data/lib/active_support/core_ext/module/deprecation.rb +15 -12
  65. data/lib/active_support/core_ext/module/introspection.rb +1 -26
  66. data/lib/active_support/core_ext/name_error.rb +23 -2
  67. data/lib/active_support/core_ext/numeric/bytes.rb +9 -0
  68. data/lib/active_support/core_ext/numeric/conversions.rb +82 -73
  69. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  70. data/lib/active_support/core_ext/object/blank.rb +2 -2
  71. data/lib/active_support/core_ext/object/deep_dup.rb +17 -1
  72. data/lib/active_support/core_ext/object/duplicable.rb +15 -4
  73. data/lib/active_support/core_ext/object/inclusion.rb +13 -5
  74. data/lib/active_support/core_ext/object/instance_variables.rb +22 -12
  75. data/lib/active_support/core_ext/object/json.rb +52 -28
  76. data/lib/active_support/core_ext/object/to_query.rb +2 -4
  77. data/lib/active_support/core_ext/object/try.rb +20 -20
  78. data/lib/active_support/core_ext/object/with.rb +44 -0
  79. data/lib/active_support/core_ext/object/with_options.rb +25 -6
  80. data/lib/active_support/core_ext/object.rb +1 -0
  81. data/lib/active_support/core_ext/pathname/blank.rb +16 -0
  82. data/lib/active_support/core_ext/pathname/existence.rb +23 -0
  83. data/lib/active_support/core_ext/pathname.rb +4 -0
  84. data/lib/active_support/core_ext/range/compare_range.rb +6 -25
  85. data/lib/active_support/core_ext/range/conversions.rb +34 -13
  86. data/lib/active_support/core_ext/range/each.rb +1 -1
  87. data/lib/active_support/core_ext/range/overlap.rb +40 -0
  88. data/lib/active_support/core_ext/range.rb +1 -2
  89. data/lib/active_support/core_ext/regexp.rb +8 -1
  90. data/lib/active_support/core_ext/securerandom.rb +25 -13
  91. data/lib/active_support/core_ext/string/access.rb +5 -24
  92. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  93. data/lib/active_support/core_ext/string/filters.rb +21 -15
  94. data/lib/active_support/core_ext/string/indent.rb +1 -1
  95. data/lib/active_support/core_ext/string/inflections.rb +51 -10
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -1
  97. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  98. data/lib/active_support/core_ext/string/output_safety.rb +85 -194
  99. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -2
  100. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  101. data/lib/active_support/core_ext/symbol.rb +3 -0
  102. data/lib/active_support/core_ext/thread/backtrace/location.rb +12 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +46 -8
  104. data/lib/active_support/core_ext/time/conversions.rb +16 -13
  105. data/lib/active_support/core_ext/time/zones.rb +12 -28
  106. data/lib/active_support/core_ext.rb +2 -1
  107. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  108. data/lib/active_support/current_attributes.rb +54 -22
  109. data/lib/active_support/deep_mergeable.rb +53 -0
  110. data/lib/active_support/dependencies/autoload.rb +17 -12
  111. data/lib/active_support/dependencies/interlock.rb +10 -18
  112. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  113. data/lib/active_support/dependencies.rb +58 -769
  114. data/lib/active_support/deprecation/behaviors.rb +77 -38
  115. data/lib/active_support/deprecation/constant_accessor.rb +5 -4
  116. data/lib/active_support/deprecation/deprecators.rb +104 -0
  117. data/lib/active_support/deprecation/disallowed.rb +54 -0
  118. data/lib/active_support/deprecation/instance_delegator.rb +31 -5
  119. data/lib/active_support/deprecation/method_wrappers.rb +12 -28
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +40 -25
  121. data/lib/active_support/deprecation/reporting.rb +76 -16
  122. data/lib/active_support/deprecation.rb +36 -4
  123. data/lib/active_support/deprecator.rb +7 -0
  124. data/lib/active_support/descendants_tracker.rb +150 -68
  125. data/lib/active_support/digest.rb +5 -3
  126. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  127. data/lib/active_support/duration/iso8601_serializer.rb +24 -12
  128. data/lib/active_support/duration.rb +136 -56
  129. data/lib/active_support/encrypted_configuration.rb +72 -9
  130. data/lib/active_support/encrypted_file.rb +46 -13
  131. data/lib/active_support/environment_inquirer.rb +40 -0
  132. data/lib/active_support/error_reporter/test_helper.rb +15 -0
  133. data/lib/active_support/error_reporter.rb +203 -0
  134. data/lib/active_support/evented_file_update_checker.rb +86 -137
  135. data/lib/active_support/execution_context/test_helper.rb +13 -0
  136. data/lib/active_support/execution_context.rb +53 -0
  137. data/lib/active_support/execution_wrapper.rb +31 -12
  138. data/lib/active_support/executor/test_helper.rb +7 -0
  139. data/lib/active_support/file_update_checker.rb +4 -2
  140. data/lib/active_support/fork_tracker.rb +79 -0
  141. data/lib/active_support/gem_version.rb +5 -5
  142. data/lib/active_support/gzip.rb +2 -0
  143. data/lib/active_support/hash_with_indifferent_access.rb +86 -42
  144. data/lib/active_support/html_safe_translation.rb +53 -0
  145. data/lib/active_support/i18n.rb +2 -1
  146. data/lib/active_support/i18n_railtie.rb +29 -27
  147. data/lib/active_support/inflector/inflections.rb +26 -9
  148. data/lib/active_support/inflector/methods.rb +54 -64
  149. data/lib/active_support/inflector/transliterate.rb +7 -5
  150. data/lib/active_support/isolated_execution_state.rb +76 -0
  151. data/lib/active_support/json/decoding.rb +6 -5
  152. data/lib/active_support/json/encoding.rb +31 -45
  153. data/lib/active_support/key_generator.rb +32 -7
  154. data/lib/active_support/lazy_load_hooks.rb +33 -7
  155. data/lib/active_support/locale/en.yml +10 -4
  156. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  157. data/lib/active_support/log_subscriber.rb +101 -32
  158. data/lib/active_support/logger.rb +9 -60
  159. data/lib/active_support/logger_silence.rb +2 -26
  160. data/lib/active_support/logger_thread_safe_level.rb +24 -25
  161. data/lib/active_support/message_encryptor.rb +205 -58
  162. data/lib/active_support/message_encryptors.rb +141 -0
  163. data/lib/active_support/message_pack/cache_serializer.rb +23 -0
  164. data/lib/active_support/message_pack/extensions.rb +292 -0
  165. data/lib/active_support/message_pack/serializer.rb +63 -0
  166. data/lib/active_support/message_pack.rb +50 -0
  167. data/lib/active_support/message_verifier.rb +237 -86
  168. data/lib/active_support/message_verifiers.rb +135 -0
  169. data/lib/active_support/messages/codec.rb +65 -0
  170. data/lib/active_support/messages/metadata.rb +112 -46
  171. data/lib/active_support/messages/rotation_configuration.rb +2 -1
  172. data/lib/active_support/messages/rotation_coordinator.rb +93 -0
  173. data/lib/active_support/messages/rotator.rb +35 -32
  174. data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
  175. data/lib/active_support/multibyte/chars.rb +15 -52
  176. data/lib/active_support/multibyte/unicode.rb +8 -122
  177. data/lib/active_support/multibyte.rb +1 -1
  178. data/lib/active_support/notifications/fanout.rb +310 -105
  179. data/lib/active_support/notifications/instrumenter.rb +113 -48
  180. data/lib/active_support/notifications.rb +56 -29
  181. data/lib/active_support/number_helper/number_converter.rb +15 -8
  182. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  183. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  184. data/lib/active_support/number_helper/number_to_human_converter.rb +1 -1
  185. data/lib/active_support/number_helper/number_to_human_size_converter.rb +5 -5
  186. data/lib/active_support/number_helper/number_to_phone_converter.rb +2 -1
  187. data/lib/active_support/number_helper/number_to_rounded_converter.rb +9 -5
  188. data/lib/active_support/number_helper/rounding_helper.rb +12 -32
  189. data/lib/active_support/number_helper.rb +379 -304
  190. data/lib/active_support/option_merger.rb +11 -18
  191. data/lib/active_support/ordered_hash.rb +4 -4
  192. data/lib/active_support/ordered_options.rb +23 -3
  193. data/lib/active_support/parameter_filter.rb +104 -75
  194. data/lib/active_support/proxy_object.rb +2 -0
  195. data/lib/active_support/rails.rb +1 -4
  196. data/lib/active_support/railtie.rb +90 -6
  197. data/lib/active_support/reloader.rb +12 -4
  198. data/lib/active_support/rescuable.rb +18 -16
  199. data/lib/active_support/ruby_features.rb +7 -0
  200. data/lib/active_support/secure_compare_rotator.rb +58 -0
  201. data/lib/active_support/security_utils.rb +19 -12
  202. data/lib/active_support/string_inquirer.rb +5 -3
  203. data/lib/active_support/subscriber.rb +23 -47
  204. data/lib/active_support/syntax_error_proxy.rb +70 -0
  205. data/lib/active_support/tagged_logging.rb +84 -23
  206. data/lib/active_support/test_case.rb +166 -27
  207. data/lib/active_support/testing/assertions.rb +73 -20
  208. data/lib/active_support/testing/autorun.rb +0 -2
  209. data/lib/active_support/testing/constant_stubbing.rb +32 -0
  210. data/lib/active_support/testing/deprecation.rb +53 -2
  211. data/lib/active_support/testing/error_reporter_assertions.rb +107 -0
  212. data/lib/active_support/testing/isolation.rb +30 -29
  213. data/lib/active_support/testing/method_call_assertions.rb +24 -11
  214. data/lib/active_support/testing/parallelization/server.rb +82 -0
  215. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  216. data/lib/active_support/testing/parallelization.rb +16 -95
  217. data/lib/active_support/testing/parallelize_executor.rb +81 -0
  218. data/lib/active_support/testing/stream.rb +4 -6
  219. data/lib/active_support/testing/strict_warnings.rb +39 -0
  220. data/lib/active_support/testing/tagged_logging.rb +1 -1
  221. data/lib/active_support/testing/time_helpers.rb +89 -19
  222. data/lib/active_support/time_with_zone.rb +105 -70
  223. data/lib/active_support/values/time_zone.rb +59 -26
  224. data/lib/active_support/version.rb +1 -1
  225. data/lib/active_support/xml_mini/jdom.rb +4 -11
  226. data/lib/active_support/xml_mini/libxml.rb +5 -5
  227. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  228. data/lib/active_support/xml_mini/nokogiri.rb +5 -5
  229. data/lib/active_support/xml_mini/nokogirisax.rb +2 -2
  230. data/lib/active_support/xml_mini/rexml.rb +9 -2
  231. data/lib/active_support/xml_mini.rb +7 -6
  232. data/lib/active_support.rb +40 -1
  233. metadata +127 -40
  234. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -5
  235. data/lib/active_support/core_ext/hash/compact.rb +0 -5
  236. data/lib/active_support/core_ext/hash/transform_values.rb +0 -5
  237. data/lib/active_support/core_ext/marshal.rb +0 -24
  238. data/lib/active_support/core_ext/module/reachable.rb +0 -6
  239. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -5
  240. data/lib/active_support/core_ext/range/include_range.rb +0 -9
  241. data/lib/active_support/core_ext/range/include_time_with_zone.rb +0 -23
  242. data/lib/active_support/core_ext/range/overlaps.rb +0 -10
  243. data/lib/active_support/core_ext/uri.rb +0 -25
  244. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -117
  245. data/lib/active_support/per_thread_registry.rb +0 -60
@@ -4,25 +4,79 @@ require "monitor"
4
4
 
5
5
  module ActiveSupport
6
6
  module Cache
7
+ # = Memory \Cache \Store
8
+ #
7
9
  # A cache store implementation which stores everything into memory in the
8
- # same process. If you're running multiple Ruby on Rails server processes
10
+ # same process. If you're running multiple Ruby on \Rails server processes
9
11
  # (which is the case if you're using Phusion Passenger or puma clustered mode),
10
- # then this means that Rails server process instances won't be able
12
+ # then this means that \Rails server process instances won't be able
11
13
  # to share cache data with each other and this may not be the most
12
14
  # appropriate cache in that scenario.
13
15
  #
14
- # This cache has a bounded size specified by the :size options to the
16
+ # This cache has a bounded size specified by the +:size+ options to the
15
17
  # initializer (default is 32Mb). When the cache exceeds the allotted size,
16
18
  # a cleanup will occur which tries to prune the cache down to three quarters
17
19
  # of the maximum size by removing the least recently used entries.
18
20
  #
19
- # MemoryStore is thread-safe.
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.
20
28
  class MemoryStore < Store
29
+ module DupCoder # :nodoc:
30
+ extend self
31
+
32
+ def dump(entry)
33
+ if entry.value && entry.value != true && !entry.value.is_a?(Numeric)
34
+ Cache::Entry.new(dump_value(entry.value), expires_at: entry.expires_at, version: entry.version)
35
+ else
36
+ entry
37
+ end
38
+ end
39
+
40
+ def dump_compressed(entry, threshold)
41
+ compressed_entry = entry.compressed(threshold)
42
+ compressed_entry.compressed? ? compressed_entry : dump(entry)
43
+ end
44
+
45
+ def load(entry)
46
+ if !entry.compressed? && entry.value.is_a?(String)
47
+ Cache::Entry.new(load_value(entry.value), expires_at: entry.expires_at, version: entry.version)
48
+ else
49
+ entry
50
+ end
51
+ end
52
+
53
+ private
54
+ MARSHAL_SIGNATURE = "\x04\x08".b.freeze
55
+
56
+ def dump_value(value)
57
+ if value.is_a?(String) && !value.start_with?(MARSHAL_SIGNATURE)
58
+ value.dup
59
+ else
60
+ Marshal.dump(value)
61
+ end
62
+ end
63
+
64
+ def load_value(string)
65
+ if string.start_with?(MARSHAL_SIGNATURE)
66
+ Marshal.load(string)
67
+ else
68
+ string.dup
69
+ end
70
+ end
71
+ end
72
+
21
73
  def initialize(options = nil)
22
74
  options ||= {}
75
+ options[:coder] = DupCoder unless options.key?(:coder) || options.key?(:serializer)
76
+ # Disable compression by default.
77
+ options[:compress] ||= false
23
78
  super(options)
24
79
  @data = {}
25
- @key_access = {}
26
80
  @max_size = options[:size] || 32.megabytes
27
81
  @max_prune_time = options[:max_prune_time] || 2
28
82
  @cache_size = 0
@@ -39,7 +93,6 @@ module ActiveSupport
39
93
  def clear(options = nil)
40
94
  synchronize do
41
95
  @data.clear
42
- @key_access.clear
43
96
  @cache_size = 0
44
97
  end
45
98
  end
@@ -47,7 +100,7 @@ module ActiveSupport
47
100
  # Preemptively iterates through all stored keys and removes the ones which have expired.
48
101
  def cleanup(options = nil)
49
102
  options = merged_options(options)
50
- instrument(:cleanup, size: @data.size) do
103
+ _instrument(:cleanup, size: @data.size) do
51
104
  keys = synchronize { @data.keys }
52
105
  keys.each do |key|
53
106
  entry = @data[key]
@@ -62,13 +115,13 @@ module ActiveSupport
62
115
  return if pruning?
63
116
  @pruning = true
64
117
  begin
65
- start_time = Concurrent.monotonic_time
118
+ start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
66
119
  cleanup
67
120
  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 } }
121
+ keys = synchronize { @data.keys }
69
122
  keys.each do |key|
70
123
  delete_entry(key, **options)
71
- return if @cache_size <= target_size || (max_time && Concurrent.monotonic_time - start_time > max_time)
124
+ return if @cache_size <= target_size || (max_time && Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time > max_time)
72
125
  end
73
126
  end
74
127
  ensure
@@ -81,12 +134,33 @@ module ActiveSupport
81
134
  @pruning
82
135
  end
83
136
 
84
- # Increment an integer value in the cache.
137
+ # Increment a cached integer value. Returns the updated value.
138
+ #
139
+ # If the key is unset, it will be set to +amount+:
140
+ #
141
+ # cache.increment("foo") # => 1
142
+ # cache.increment("bar", 100) # => 100
143
+ #
144
+ # To set a specific value, call #write:
145
+ #
146
+ # cache.write("baz", 5)
147
+ # cache.increment("baz") # => 6
148
+ #
85
149
  def increment(name, amount = 1, options = nil)
86
150
  modify_value(name, amount, options)
87
151
  end
88
152
 
89
- # Decrement an integer value in the cache.
153
+ # Decrement a cached integer value. Returns the updated value.
154
+ #
155
+ # If the key is unset or has expired, it will be set to +-amount+.
156
+ #
157
+ # cache.decrement("foo") # => -1
158
+ #
159
+ # To set a specific value, call #write:
160
+ #
161
+ # cache.write("baz", 5)
162
+ # cache.decrement("baz") # => 4
163
+ #
90
164
  def decrement(name, amount = 1, options = nil)
91
165
  modify_value(name, -amount, options)
92
166
  end
@@ -104,7 +178,7 @@ module ActiveSupport
104
178
  end
105
179
 
106
180
  def inspect # :nodoc:
107
- "<##{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>"
181
+ "#<#{self.class.name} entries=#{@data.size}, size=#{@cache_size}, options=#{@options.inspect}>"
108
182
  end
109
183
 
110
184
  # Synchronize calls to the cache. This should be called wherever the underlying cache implementation
@@ -116,36 +190,34 @@ module ActiveSupport
116
190
  private
117
191
  PER_ENTRY_OVERHEAD = 240
118
192
 
119
- def cached_size(key, entry)
120
- key.to_s.bytesize + entry.size + PER_ENTRY_OVERHEAD
193
+ def cached_size(key, payload)
194
+ key.to_s.bytesize + payload.bytesize + PER_ENTRY_OVERHEAD
121
195
  end
122
196
 
123
197
  def read_entry(key, **options)
124
- entry = @data[key]
198
+ entry = nil
125
199
  synchronize do
126
- if entry
127
- entry = entry.dup
128
- entry.dup_value!
129
- @key_access[key] = Time.now.to_f
130
- else
131
- @key_access.delete(key)
200
+ payload = @data.delete(key)
201
+ if payload
202
+ @data[key] = payload
203
+ entry = deserialize_entry(payload)
132
204
  end
133
205
  end
134
206
  entry
135
207
  end
136
208
 
137
209
  def write_entry(key, entry, **options)
138
- entry.dup_value!
210
+ payload = serialize_entry(entry, **options)
139
211
  synchronize do
140
- old_entry = @data[key]
141
- return false if @data.key?(key) && options[:unless_exist]
142
- if old_entry
143
- @cache_size -= (old_entry.size - entry.size)
212
+ return false if options[:unless_exist] && exist?(key, namespace: nil)
213
+
214
+ old_payload = @data[key]
215
+ if old_payload
216
+ @cache_size -= (old_payload.bytesize - payload.bytesize)
144
217
  else
145
- @cache_size += cached_size(key, entry)
218
+ @cache_size += cached_size(key, payload)
146
219
  end
147
- @key_access[key] = Time.now.to_f
148
- @data[key] = entry
220
+ @data[key] = payload
149
221
  prune(@max_size * 0.75, @max_prune_time) if @cache_size > @max_size
150
222
  true
151
223
  end
@@ -153,19 +225,29 @@ module ActiveSupport
153
225
 
154
226
  def delete_entry(key, **options)
155
227
  synchronize do
156
- @key_access.delete(key)
157
- entry = @data.delete(key)
158
- @cache_size -= cached_size(key, entry) if entry
159
- !!entry
228
+ payload = @data.delete(key)
229
+ @cache_size -= cached_size(key, payload) if payload
230
+ !!payload
160
231
  end
161
232
  end
162
233
 
234
+ # Modifies the amount of an integer value that is stored in the cache.
235
+ # If the key is not found it is created and set to +amount+.
163
236
  def modify_value(name, amount, options)
237
+ options = merged_options(options)
238
+ key = normalize_key(name, options)
239
+ version = normalize_version(name, options)
240
+
164
241
  synchronize do
165
- options = merged_options(options)
166
- if num = read(name, options)
167
- num = num.to_i + amount
168
- write(name, num, options)
242
+ entry = read_entry(key, **options)
243
+
244
+ if !entry || entry.expired? || entry.mismatched?(version)
245
+ write(name, Integer(amount), options)
246
+ amount
247
+ else
248
+ num = entry.value.to_i + amount
249
+ entry = Entry.new(num, expires_at: entry.expires_at, version: entry.version)
250
+ write_entry(key, entry)
169
251
  num
170
252
  end
171
253
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module ActiveSupport
4
4
  module Cache
5
+ # = Null \Cache \Store
6
+ #
5
7
  # A cache store implementation which doesn't actually store anything. Useful in
6
8
  # development and test environments where you don't want caching turned on but
7
9
  # need to go through the caching interface.
@@ -32,11 +34,23 @@ module ActiveSupport
32
34
  def delete_matched(matcher, options = nil)
33
35
  end
34
36
 
37
+ def inspect # :nodoc:
38
+ "#<#{self.class.name} options=#{@options.inspect}>"
39
+ end
40
+
35
41
  private
36
- def read_entry(key, **options)
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))
37
51
  end
38
52
 
39
- def write_entry(key, entry, **options)
53
+ def write_serialized_entry(_key, _payload, **)
40
54
  true
41
55
  end
42
56