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.

Files changed (264) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +412 -444
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +8 -4
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +14 -12
  8. data/lib/active_support/benchmarkable.rb +6 -14
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +67 -51
  11. data/lib/active_support/cache/mem_cache_store.rb +95 -97
  12. data/lib/active_support/cache/memory_store.rb +28 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +70 -56
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  17. data/lib/active_support/cache.rb +331 -206
  18. data/lib/active_support/callbacks.rb +697 -426
  19. data/lib/active_support/concern.rb +32 -10
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +39 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +24 -35
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +23 -13
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -5
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -7
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -23
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  37. data/lib/active_support/core_ext/class.rb +4 -4
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +21 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +32 -22
  42. data/lib/active_support/core_ext/date/zones.rb +5 -34
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +199 -57
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +41 -0
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +78 -37
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  51. data/lib/active_support/core_ext/date_time/conversions.rb +19 -13
  52. data/lib/active_support/core_ext/date_time.rb +7 -4
  53. data/lib/active_support/core_ext/digest/uuid.rb +53 -0
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +113 -29
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +29 -0
  59. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +12 -3
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +50 -38
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +12 -6
  66. data/lib/active_support/core_ext/hash/transform_values.rb +32 -0
  67. data/lib/active_support/core_ext/hash.rb +11 -8
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -33
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +5 -74
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -4
  77. data/lib/active_support/core_ext/load_error.rb +5 -21
  78. data/lib/active_support/core_ext/marshal.rb +13 -10
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +170 -21
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +134 -0
  85. data/lib/active_support/core_ext/module/delegation.rb +135 -45
  86. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -25
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -10
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +70 -19
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  102. data/lib/active_support/core_ext/object/duplicable.rb +100 -34
  103. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +227 -0
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  108. data/lib/active_support/core_ext/object/try.rb +94 -24
  109. data/lib/active_support/core_ext/object/with_options.rb +45 -5
  110. data/lib/active_support/core_ext/object.rb +14 -12
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +41 -39
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +17 -13
  123. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  124. data/lib/active_support/core_ext/string/filters.rb +55 -6
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +66 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +114 -54
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -1
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +123 -110
  136. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  137. data/lib/active_support/core_ext/time/conversions.rb +23 -14
  138. data/lib/active_support/core_ext/time/zones.rb +42 -26
  139. data/lib/active_support/core_ext/time.rb +7 -5
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -2
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +3 -1
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +196 -166
  146. data/lib/active_support/deprecation/behaviors.rb +48 -15
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +14 -11
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +354 -34
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +128 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +17 -0
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +158 -35
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +38 -20
  169. data/lib/active_support/inflections.rb +19 -12
  170. data/lib/active_support/inflector/inflections.rb +79 -30
  171. data/lib/active_support/inflector/methods.rb +197 -129
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +21 -25
  175. data/lib/active_support/json/encoding.rb +84 -292
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +26 -28
  178. data/lib/active_support/lazy_load_hooks.rb +51 -21
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +54 -3
  183. data/lib/active_support/logger_silence.rb +12 -7
  184. data/lib/active_support/logger_thread_safe_level.rb +34 -0
  185. data/lib/active_support/message_encryptor.rb +173 -50
  186. data/lib/active_support/message_verifier.rb +159 -22
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +38 -26
  191. data/lib/active_support/multibyte/unicode.rb +138 -146
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +23 -16
  194. data/lib/active_support/notifications/instrumenter.rb +29 -8
  195. data/lib/active_support/notifications.rb +22 -13
  196. data/lib/active_support/number_helper/number_converter.rb +184 -0
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +29 -0
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +59 -0
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +14 -0
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +54 -0
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +125 -391
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +31 -5
  209. data/lib/active_support/per_thread_registry.rb +19 -11
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +31 -0
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +54 -17
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +42 -37
  220. data/lib/active_support/testing/assertions.rb +126 -39
  221. data/lib/active_support/testing/autorun.rb +5 -3
  222. data/lib/active_support/testing/constant_lookup.rb +3 -6
  223. data/lib/active_support/testing/declarative.rb +10 -22
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +55 -86
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +5 -3
  231. data/lib/active_support/testing/time_helpers.rb +200 -0
  232. data/lib/active_support/time.rb +13 -13
  233. data/lib/active_support/time_with_zone.rb +223 -73
  234. data/lib/active_support/values/time_zone.rb +261 -126
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +6 -7
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. data/lib/active_support/xml_mini.rb +69 -51
  244. data/lib/active_support.rb +29 -3
  245. metadata +84 -54
  246. data/lib/active_support/basic_object.rb +0 -11
  247. data/lib/active_support/buffered_logger.rb +0 -21
  248. data/lib/active_support/concurrency/latch.rb +0 -27
  249. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  250. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  251. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  252. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  253. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  254. data/lib/active_support/core_ext/logger.rb +0 -67
  255. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  256. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  257. data/lib/active_support/core_ext/proc.rb +0 -17
  258. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  259. data/lib/active_support/core_ext/struct.rb +0 -6
  260. data/lib/active_support/core_ext/thread.rb +0 -79
  261. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  262. data/lib/active_support/file_watcher.rb +0 -36
  263. data/lib/active_support/json/variable.rb +0 -18
  264. data/lib/active_support/testing/pending.rb +0 -14
@@ -1,18 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
- require 'dalli'
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 'digest/md5'
9
- require 'active_support/core_ext/marshal'
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
- # http://memcached.org/
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
- def self.build_mem_cache(*addresses)
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
- Dalli::Client.new(addresses, options)
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
- if addresses.first.respond_to?(:get)
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) # :nodoc:
97
+ def increment(name, amount = 1, options = nil)
86
98
  options = merged_options(options)
87
- instrument(:increment, name, :amount => amount) do
88
- @data.incr(escape_key(namespaced_key(name, options)), amount)
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) # :nodoc:
110
+ def decrement(name, amount = 1, options = nil)
100
111
  options = merged_options(options)
101
- instrument(:decrement, name, :amount => amount) do
102
- @data.decr(escape_key(namespaced_key(name, options)), amount)
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
- protected
130
+ private
124
131
  # Read an entry from the cache.
125
- def read_entry(key, options) # :nodoc:
126
- deserialize_entry(@data.get(escape_key(key), options))
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) # :nodoc:
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
- @data.send(method, escape_key(key), value, expires_in, options)
142
- rescue Dalli::DalliError => e
143
- logger.error("DalliError (#{e}): #{e.message}") if logger
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
- # Delete an entry from the cache.
148
- def delete_entry(key, options) # :nodoc:
149
- @data.delete(escape_key(key))
150
- rescue Dalli::DalliError => e
151
- logger.error("DalliError (#{e}): #{e.message}") if logger
152
- false
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
- private
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 escape_key(key)
161
- key = key.to_s.dup
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::MD5.hexdigest(key)}" if key.size > 250
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(raw_value)
169
- if raw_value
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
- # Provide support for raw values in the local cache strategy.
178
- module LocalCacheWithRaw # :nodoc:
179
- protected
180
- def read_entry(key, options)
181
- entry = super
182
- if options[:raw] && local_cache && entry
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
- require 'monitor'
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 mongrel_cluster or Phusion Passenger),
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, :size => @data.size) do
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, :from => @cache_size) do
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
- synchronize do
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
- synchronize do
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
- protected
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) # :nodoc:
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) # :nodoc:
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) # :nodoc:
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
- def initialize(options = nil)
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
- protected
32
- def read_entry(key, options) # :nodoc:
30
+ private
31
+ def read_entry(key, options)
33
32
  end
34
33
 
35
- def write_entry(key, entry, options) # :nodoc:
34
+ def write_entry(key, entry, options)
36
35
  true
37
36
  end
38
37
 
39
- def delete_entry(key, options) # :nodoc:
38
+ def delete_entry(key, options)
40
39
  false
41
40
  end
42
41
  end