activesupport 4.2.11.1 → 5.2.4.3

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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +403 -433
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  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 +7 -5
  8. data/lib/active_support/benchmarkable.rb +6 -4
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +41 -35
  11. data/lib/active_support/cache/mem_cache_store.rb +90 -91
  12. data/lib/active_support/cache/memory_store.rb +27 -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 +67 -34
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  17. data/lib/active_support/cache.rb +287 -196
  18. data/lib/active_support/callbacks.rb +640 -590
  19. data/lib/active_support/concern.rb +11 -5
  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 +29 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -6
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  37. data/lib/active_support/core_ext/class.rb +4 -3
  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 +11 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  42. data/lib/active_support/core_ext/date/zones.rb +4 -2
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  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 +36 -18
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  51. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  52. data/lib/active_support/core_ext/date_time.rb +7 -5
  53. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +101 -33
  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 +14 -9
  59. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +11 -8
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  66. data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
  67. data/lib/active_support/core_ext/hash.rb +11 -9
  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 -18
  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 +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +8 -8
  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 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  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 +11 -12
  85. data/lib/active_support/core_ext/module/delegation.rb +99 -29
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  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 -11
  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 +78 -81
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  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 +27 -2
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  102. data/lib/active_support/core_ext/object/duplicable.rb +41 -14
  103. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +49 -19
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  108. data/lib/active_support/core_ext/object/try.rb +69 -21
  109. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  110. data/lib/active_support/core_ext/object.rb +14 -13
  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 +8 -6
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  123. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  124. data/lib/active_support/core_ext/string/filters.rb +6 -5
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +61 -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 +34 -38
  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 -2
  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 +85 -51
  136. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  137. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  138. data/lib/active_support/core_ext/time/zones.rb +41 -7
  139. data/lib/active_support/core_ext/time.rb +7 -6
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -1
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +152 -161
  146. data/lib/active_support/deprecation/behaviors.rb +44 -11
  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 +12 -9
  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 +307 -35
  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 +6 -4
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +123 -28
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +37 -13
  169. data/lib/active_support/inflections.rb +13 -11
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +163 -136
  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 +16 -13
  175. data/lib/active_support/json/encoding.rb +11 -58
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +25 -25
  178. data/lib/active_support/lazy_load_hooks.rb +50 -20
  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 +8 -7
  183. data/lib/active_support/logger_silence.rb +6 -4
  184. data/lib/active_support/logger_thread_safe_level.rb +7 -5
  185. data/lib/active_support/message_encryptor.rb +168 -53
  186. data/lib/active_support/message_verifier.rb +150 -17
  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 +36 -23
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +11 -9
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/notifications.rb +11 -7
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +94 -68
  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 +23 -5
  209. data/lib/active_support/per_thread_registry.rb +9 -4
  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 +15 -11
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +21 -16
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +19 -47
  220. data/lib/active_support/testing/assertions.rb +137 -20
  221. data/lib/active_support/testing/autorun.rb +4 -2
  222. data/lib/active_support/testing/constant_lookup.rb +2 -1
  223. data/lib/active_support/testing/declarative.rb +3 -1
  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 +34 -25
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +3 -1
  231. data/lib/active_support/testing/time_helpers.rb +81 -15
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +169 -39
  234. data/lib/active_support/values/time_zone.rb +196 -61
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +3 -1
  237. data/lib/active_support/xml_mini/jdom.rb +116 -114
  238. data/lib/active_support/xml_mini/libxml.rb +16 -13
  239. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  240. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  241. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  242. data/lib/active_support/xml_mini/rexml.rb +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +54 -24
  246. data/lib/active_support/concurrency/latch.rb +0 -27
  247. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  248. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  249. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  250. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  251. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  252. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  253. data/lib/active_support/core_ext/object/itself.rb +0 -15
  254. data/lib/active_support/core_ext/struct.rb +0 -6
  255. data/lib/active_support/core_ext/thread.rb +0 -86
  256. data/lib/active_support/core_ext/time/marshal.rb +0 -30
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2005-2014 David Heinemeier Hansson
1
+ Copyright (c) 2005-2018 David Heinemeier Hansson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
17
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc CHANGED
@@ -10,18 +10,18 @@ outside of Rails.
10
10
 
11
11
  The latest version of Active Support can be installed with RubyGems:
12
12
 
13
- % [sudo] gem install activesupport
13
+ $ gem install activesupport
14
14
 
15
15
  Source code can be downloaded as part of the Rails project on GitHub:
16
16
 
17
- * https://github.com/rails/rails/tree/4-2-stable/activesupport
17
+ * https://github.com/rails/rails/tree/5-2-stable/activesupport
18
18
 
19
19
 
20
20
  == License
21
21
 
22
22
  Active Support is released under the MIT license:
23
23
 
24
- * http://www.opensource.org/licenses/MIT
24
+ * https://opensource.org/licenses/MIT
25
25
 
26
26
 
27
27
  == Support
@@ -30,11 +30,10 @@ API documentation is at:
30
30
 
31
31
  * http://api.rubyonrails.org
32
32
 
33
- Bug reports can be filed for the Ruby on Rails project here:
33
+ Bug reports for the Ruby on Rails project can be filed here:
34
34
 
35
35
  * https://github.com/rails/rails/issues
36
36
 
37
37
  Feature requests should be discussed on the rails-core mailing list here:
38
38
 
39
39
  * https://groups.google.com/forum/?fromgroups#!forum/rubyonrails-core
40
-
@@ -1,3 +1,5 @@
1
- require 'active_support'
2
- require 'active_support/time'
3
- require 'active_support/core_ext'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/time"
5
+ require "active_support/core_ext"
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ # Wrapping an array in an +ArrayInquirer+ gives a friendlier way to check
5
+ # its string-like contents:
6
+ #
7
+ # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
8
+ #
9
+ # variants.phone? # => true
10
+ # variants.tablet? # => true
11
+ # variants.desktop? # => false
12
+ class ArrayInquirer < Array
13
+ # Passes each element of +candidates+ collection to ArrayInquirer collection.
14
+ # The method returns true if any element from the ArrayInquirer collection
15
+ # is equal to the stringified or symbolized form of any element in the +candidates+ collection.
16
+ #
17
+ # If +candidates+ collection is not given, method returns true.
18
+ #
19
+ # variants = ActiveSupport::ArrayInquirer.new([:phone, :tablet])
20
+ #
21
+ # variants.any? # => true
22
+ # variants.any?(:phone, :tablet) # => true
23
+ # variants.any?('phone', 'desktop') # => true
24
+ # variants.any?(:desktop, :watch) # => false
25
+ def any?(*candidates)
26
+ if candidates.none?
27
+ super
28
+ else
29
+ candidates.any? do |candidate|
30
+ include?(candidate.to_sym) || include?(candidate.to_s)
31
+ end
32
+ end
33
+ end
34
+
35
+ private
36
+ def respond_to_missing?(name, include_private = false)
37
+ (name[-1] == "?") || super
38
+ end
39
+
40
+ def method_missing(name, *args)
41
+ if name[-1] == "?"
42
+ any?(name[0..-2])
43
+ else
44
+ super
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # Backtraces often include many lines that are not relevant for the context
3
5
  # under review. This makes it hard to find the signal amongst the backtrace
@@ -12,9 +14,9 @@ module ActiveSupport
12
14
  # is to exclude the output of a noisy library from the backtrace, so that you
13
15
  # can focus on the rest.
14
16
  #
15
- # bc = BacktraceCleaner.new
17
+ # bc = ActiveSupport::BacktraceCleaner.new
16
18
  # bc.add_filter { |line| line.gsub(Rails.root.to_s, '') } # strip the Rails.root prefix
17
- # bc.add_silencer { |line| line =~ /mongrel|rubygems/ } # skip any lines from mongrel or rubygems
19
+ # bc.add_silencer { |line| line =~ /puma|rubygems/ } # skip any lines from puma or rubygems
18
20
  # bc.clean(exception.backtrace) # perform the cleanup
19
21
  #
20
22
  # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
@@ -25,7 +27,7 @@ module ActiveSupport
25
27
  # of the backtrace, you can call <tt>BacktraceCleaner#remove_filters!</tt>
26
28
  # These two methods will give you a completely untouched backtrace.
27
29
  #
28
- # Inspired by the Quiet Backtrace gem by Thoughtbot.
30
+ # Inspired by the Quiet Backtrace gem by thoughtbot.
29
31
  class BacktraceCleaner
30
32
  def initialize
31
33
  @filters, @silencers = [], []
@@ -59,8 +61,8 @@ module ActiveSupport
59
61
  # Adds a silencer from the block provided. If the silencer returns +true+
60
62
  # for a given line, it will be excluded from the clean backtrace.
61
63
  #
62
- # # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
63
- # backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
64
+ # # Will reject all lines that include the word "puma", like "/gems/puma/server.rb" or "/app/my_puma_server/rb"
65
+ # backtrace_cleaner.add_silencer { |line| line =~ /puma/ }
64
66
  def add_silencer(&block)
65
67
  @silencers << block
66
68
  end
@@ -1,5 +1,7 @@
1
- require 'active_support/core_ext/benchmark'
2
- require 'active_support/core_ext/hash/keys'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/benchmark"
4
+ require "active_support/core_ext/hash/keys"
3
5
 
4
6
  module ActiveSupport
5
7
  module Benchmarkable
@@ -38,8 +40,8 @@ module ActiveSupport
38
40
  options[:level] ||= :info
39
41
 
40
42
  result = nil
41
- ms = Benchmark.ms { result = options[:silence] ? silence { yield } : yield }
42
- logger.send(options[:level], '%s (%.1fms)' % [ message, ms ])
43
+ ms = Benchmark.ms { result = options[:silence] ? logger.silence { yield } : yield }
44
+ logger.send(options[:level], "%s (%.1fms)" % [ message, ms ])
43
45
  result
44
46
  else
45
47
  yield
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  begin
2
- require 'builder'
4
+ require "builder"
3
5
  rescue LoadError => e
4
6
  $stderr.puts "You don't have builder installed in your application. Please add it to your Gemfile and run bundle install"
5
7
  raise e
@@ -1,7 +1,9 @@
1
- require 'active_support/core_ext/marshal'
2
- require 'active_support/core_ext/file/atomic'
3
- require 'active_support/core_ext/string/conversions'
4
- require 'uri/common'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/marshal"
4
+ require "active_support/core_ext/file/atomic"
5
+ require "active_support/core_ext/string/conversions"
6
+ require "uri/common"
5
7
 
6
8
  module ActiveSupport
7
9
  module Cache
@@ -10,34 +12,35 @@ module ActiveSupport
10
12
  # FileStore implements the Strategy::LocalCache strategy which implements
11
13
  # an in-memory cache inside of a block.
12
14
  class FileStore < Store
15
+ prepend Strategy::LocalCache
13
16
  attr_reader :cache_path
14
17
 
15
18
  DIR_FORMATTER = "%03X"
16
19
  FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
17
20
  FILEPATH_MAX_SIZE = 900 # max is 1024, plus some room
18
- EXCLUDED_DIRS = ['.', '..'].freeze
21
+ EXCLUDED_DIRS = [".", ".."].freeze
22
+ GITKEEP_FILES = [".gitkeep", ".keep"].freeze
19
23
 
20
24
  def initialize(cache_path, options = nil)
21
25
  super(options)
22
26
  @cache_path = cache_path.to_s
23
- extend Strategy::LocalCache
24
27
  end
25
28
 
26
29
  # Deletes all items from the cache. In this case it deletes all the entries in the specified
27
- # file store directory except for .gitkeep. Be careful which directory is specified in your
30
+ # file store directory except for .keep or .gitkeep. Be careful which directory is specified in your
28
31
  # config file when using +FileStore+ because everything in that directory will be deleted.
29
32
  def clear(options = nil)
30
- root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)}
31
- FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
33
+ root_dirs = exclude_from(cache_path, EXCLUDED_DIRS + GITKEEP_FILES)
34
+ FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) })
35
+ rescue Errno::ENOENT
32
36
  end
33
37
 
34
38
  # Preemptively iterates through all stored keys and removes the ones which have expired.
35
39
  def cleanup(options = nil)
36
40
  options = merged_options(options)
37
41
  search_dir(cache_path) do |fname|
38
- key = file_path_key(fname)
39
- entry = read_entry(key, options)
40
- delete_entry(key, options) if entry && entry.expired?
42
+ entry = read_entry(fname, options)
43
+ delete_entry(fname, options) if entry && entry.expired?
41
44
  end
42
45
  end
43
46
 
@@ -59,17 +62,16 @@ module ActiveSupport
59
62
  matcher = key_matcher(matcher, options)
60
63
  search_dir(cache_path) do |path|
61
64
  key = file_path_key(path)
62
- delete_entry(key, options) if key.match(matcher)
65
+ delete_entry(path, options) if key.match(matcher)
63
66
  end
64
67
  end
65
68
  end
66
69
 
67
- protected
70
+ private
68
71
 
69
72
  def read_entry(key, options)
70
- file_name = key_file_path(key)
71
- if File.exist?(file_name)
72
- File.open(file_name) { |f| Marshal.load(f) }
73
+ if File.exist?(key)
74
+ File.open(key) { |f| Marshal.load(f) }
73
75
  end
74
76
  rescue => e
75
77
  logger.error("FileStoreError (#{e}): #{e.message}") if logger
@@ -77,33 +79,30 @@ module ActiveSupport
77
79
  end
78
80
 
79
81
  def write_entry(key, entry, options)
80
- file_name = key_file_path(key)
81
- return false if options[:unless_exist] && File.exist?(file_name)
82
- ensure_cache_path(File.dirname(file_name))
83
- File.atomic_write(file_name, cache_path) {|f| Marshal.dump(entry, f)}
82
+ return false if options[:unless_exist] && File.exist?(key)
83
+ ensure_cache_path(File.dirname(key))
84
+ File.atomic_write(key, cache_path) { |f| Marshal.dump(entry, f) }
84
85
  true
85
86
  end
86
87
 
87
88
  def delete_entry(key, options)
88
- file_name = key_file_path(key)
89
- if File.exist?(file_name)
89
+ if File.exist?(key)
90
90
  begin
91
- File.delete(file_name)
92
- delete_empty_directories(File.dirname(file_name))
91
+ File.delete(key)
92
+ delete_empty_directories(File.dirname(key))
93
93
  true
94
94
  rescue => e
95
95
  # Just in case the error was caused by another process deleting the file first.
96
- raise e if File.exist?(file_name)
96
+ raise e if File.exist?(key)
97
97
  false
98
98
  end
99
99
  end
100
100
  end
101
101
 
102
- private
103
102
  # Lock a file for a block so only one process can modify it at a time.
104
- def lock_file(file_name, &block) # :nodoc:
103
+ def lock_file(file_name, &block)
105
104
  if File.exist?(file_name)
106
- File.open(file_name, 'r+') do |f|
105
+ File.open(file_name, "r+") do |f|
107
106
  begin
108
107
  f.flock File::LOCK_EX
109
108
  yield
@@ -117,12 +116,14 @@ module ActiveSupport
117
116
  end
118
117
 
119
118
  # Translate a key into a file path.
120
- def key_file_path(key)
121
- if key.size > FILEPATH_MAX_SIZE
122
- key = Digest::MD5.hexdigest(key)
119
+ def normalize_key(key, options)
120
+ key = super
121
+ fname = URI.encode_www_form_component(key)
122
+
123
+ if fname.size > FILEPATH_MAX_SIZE
124
+ fname = ActiveSupport::Digest.hexdigest(key)
123
125
  end
124
126
 
125
- fname = URI.encode_www_form_component(key)
126
127
  hash = Zlib.adler32(fname)
127
128
  hash, dir_1 = hash.divmod(0x1000)
128
129
  dir_2 = hash.modulo(0x1000)
@@ -146,7 +147,7 @@ module ActiveSupport
146
147
  # Delete empty directories in the cache.
147
148
  def delete_empty_directories(dir)
148
149
  return if File.realpath(dir) == File.realpath(cache_path)
149
- if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty?
150
+ if exclude_from(dir, EXCLUDED_DIRS).empty?
150
151
  Dir.delete(dir) rescue nil
151
152
  delete_empty_directories(File.dirname(dir))
152
153
  end
@@ -173,7 +174,7 @@ module ActiveSupport
173
174
  # Modifies the amount of an already existing integer value that is stored in the cache.
174
175
  # If the key is not found nothing is done.
175
176
  def modify_value(name, amount, options)
176
- file_name = key_file_path(namespaced_key(name, options))
177
+ file_name = normalize_key(name, options)
177
178
 
178
179
  lock_file(file_name) do
179
180
  options = merged_options(options)
@@ -185,6 +186,11 @@ module ActiveSupport
185
186
  end
186
187
  end
187
188
  end
189
+
190
+ # Exclude entries from source directory
191
+ def exclude_from(source, excludes)
192
+ Dir.entries(source).reject { |f| excludes.include?(f) }
193
+ end
188
194
  end
189
195
  end
190
196
  end
@@ -1,18 +1,18 @@
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/array/extract_options"
11
11
 
12
12
  module ActiveSupport
13
13
  module Cache
14
14
  # A cache store implementation which stores data in Memcached:
15
- # http://memcached.org/
15
+ # https://memcached.org
16
16
  #
17
17
  # This is currently the most popular cache store for production websites.
18
18
  #
@@ -24,13 +24,44 @@ module ActiveSupport
24
24
  # MemCacheStore implements the Strategy::LocalCache strategy which implements
25
25
  # an in-memory cache inside of a block.
26
26
  class MemCacheStore < Store
27
+ # Provide support for raw values in the local cache strategy.
28
+ module LocalCacheWithRaw # :nodoc:
29
+ private
30
+ def write_entry(key, entry, options)
31
+ if options[:raw] && local_cache
32
+ raw_entry = Entry.new(entry.value.to_s)
33
+ raw_entry.expires_at = entry.expires_at
34
+ super(key, raw_entry, options)
35
+ else
36
+ super
37
+ end
38
+ end
39
+ end
40
+
41
+ prepend Strategy::LocalCache
42
+ prepend LocalCacheWithRaw
43
+
27
44
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
28
45
 
29
- def self.build_mem_cache(*addresses)
46
+ # Creates a new Dalli::Client instance with specified addresses and options.
47
+ # By default address is equal localhost:11211.
48
+ #
49
+ # ActiveSupport::Cache::MemCacheStore.build_mem_cache
50
+ # # => #<Dalli::Client:0x007f98a47d2028 @servers=["localhost:11211"], @options={}, @ring=nil>
51
+ # ActiveSupport::Cache::MemCacheStore.build_mem_cache('localhost:10290')
52
+ # # => #<Dalli::Client:0x007f98a47b3a60 @servers=["localhost:10290"], @options={}, @ring=nil>
53
+ def self.build_mem_cache(*addresses) # :nodoc:
30
54
  addresses = addresses.flatten
31
55
  options = addresses.extract_options!
32
56
  addresses = ["localhost:11211"] if addresses.empty?
33
- Dalli::Client.new(addresses, options)
57
+ pool_options = retrieve_pool_options(options)
58
+
59
+ if pool_options.empty?
60
+ Dalli::Client.new(addresses, options)
61
+ else
62
+ ensure_connection_pool_added!
63
+ ConnectionPool.new(pool_options) { Dalli::Client.new(addresses, options.merge(threadsafe: false)) }
64
+ end
34
65
  end
35
66
 
36
67
  # Creates a new MemCacheStore object, with the given memcached server
@@ -53,82 +84,56 @@ module ActiveSupport
53
84
  @data = addresses.first
54
85
  else
55
86
  mem_cache_options = options.dup
56
- UNIVERSAL_OPTIONS.each{|name| mem_cache_options.delete(name)}
87
+ UNIVERSAL_OPTIONS.each { |name| mem_cache_options.delete(name) }
57
88
  @data = self.class.build_mem_cache(*(addresses + [mem_cache_options]))
58
89
  end
59
-
60
- extend Strategy::LocalCache
61
- extend LocalCacheWithRaw
62
- end
63
-
64
- # Reads multiple values from the cache using a single call to the
65
- # servers for all keys. Options can be passed in the last argument.
66
- def read_multi(*names)
67
- options = names.extract_options!
68
- options = merged_options(options)
69
- keys_to_names = Hash[names.map{|name| [escape_key(namespaced_key(name, options)), name]}]
70
- raw_values = @data.get_multi(keys_to_names.keys)
71
- values = {}
72
- raw_values.each do |key, value|
73
- entry = deserialize_entry(value)
74
- values[keys_to_names[key]] = entry.value unless entry.expired?
75
- end
76
- values
77
90
  end
78
91
 
79
92
  # Increment a cached value. This method uses the memcached incr atomic
80
93
  # operator and can only be used on values written with the :raw option.
81
94
  # Calling it on a value not stored with :raw will initialize that value
82
95
  # to zero.
83
- def increment(name, amount = 1, options = nil) # :nodoc:
96
+ def increment(name, amount = 1, options = nil)
84
97
  options = merged_options(options)
85
- instrument(:increment, name, :amount => amount) do
86
- @data.incr(escape_key(namespaced_key(name, options)), amount)
98
+ instrument(:increment, name, amount: amount) do
99
+ rescue_error_with nil do
100
+ @data.with { |c| c.incr(normalize_key(name, options), amount, options[:expires_in]) }
101
+ end
87
102
  end
88
- rescue Dalli::DalliError => e
89
- logger.error("DalliError (#{e}): #{e.message}") if logger
90
- nil
91
103
  end
92
104
 
93
105
  # Decrement a cached value. This method uses the memcached decr atomic
94
106
  # operator and can only be used on values written with the :raw option.
95
107
  # Calling it on a value not stored with :raw will initialize that value
96
108
  # to zero.
97
- def decrement(name, amount = 1, options = nil) # :nodoc:
109
+ def decrement(name, amount = 1, options = nil)
98
110
  options = merged_options(options)
99
- instrument(:decrement, name, :amount => amount) do
100
- @data.decr(escape_key(namespaced_key(name, options)), amount)
111
+ instrument(:decrement, name, amount: amount) do
112
+ rescue_error_with nil do
113
+ @data.with { |c| c.decr(normalize_key(name, options), amount, options[:expires_in]) }
114
+ end
101
115
  end
102
- rescue Dalli::DalliError => e
103
- logger.error("DalliError (#{e}): #{e.message}") if logger
104
- nil
105
116
  end
106
117
 
107
118
  # Clear the entire cache on all memcached servers. This method should
108
119
  # be used with care when shared cache is being used.
109
120
  def clear(options = nil)
110
- @data.flush_all
111
- rescue Dalli::DalliError => e
112
- logger.error("DalliError (#{e}): #{e.message}") if logger
113
- nil
121
+ rescue_error_with(nil) { @data.with { |c| c.flush_all } }
114
122
  end
115
123
 
116
124
  # Get the statistics from the memcached servers.
117
125
  def stats
118
- @data.stats
126
+ @data.with { |c| c.stats }
119
127
  end
120
128
 
121
- protected
129
+ private
122
130
  # Read an entry from the cache.
123
- def read_entry(key, options) # :nodoc:
124
- deserialize_entry(@data.get(escape_key(key), options))
125
- rescue Dalli::DalliError => e
126
- logger.error("DalliError (#{e}): #{e.message}") if logger
127
- nil
131
+ def read_entry(key, options)
132
+ rescue_error_with(nil) { deserialize_entry(@data.with { |c| c.get(key, options) }) }
128
133
  end
129
134
 
130
135
  # Write an entry to the cache.
131
- def write_entry(key, entry, options) # :nodoc:
136
+ def write_entry(key, entry, options)
132
137
  method = options && options[:unless_exist] ? :add : :set
133
138
  value = options[:raw] ? entry.value.to_s : entry
134
139
  expires_in = options[:expires_in].to_i
@@ -136,63 +141,57 @@ module ActiveSupport
136
141
  # Set the memcache expire a few minutes in the future to support race condition ttls on read
137
142
  expires_in += 5.minutes
138
143
  end
139
- @data.send(method, escape_key(key), value, expires_in, options)
140
- rescue Dalli::DalliError => e
141
- logger.error("DalliError (#{e}): #{e.message}") if logger
142
- false
144
+ rescue_error_with false do
145
+ @data.with { |c| c.send(method, key, value, expires_in, options) }
146
+ end
143
147
  end
144
148
 
145
- # Delete an entry from the cache.
146
- def delete_entry(key, options) # :nodoc:
147
- @data.delete(escape_key(key))
148
- rescue Dalli::DalliError => e
149
- logger.error("DalliError (#{e}): #{e.message}") if logger
150
- false
149
+ # Reads multiple entries from the cache implementation.
150
+ def read_multi_entries(names, options)
151
+ keys_to_names = Hash[names.map { |name| [normalize_key(name, options), name] }]
152
+
153
+ raw_values = @data.with { |c| c.get_multi(keys_to_names.keys) }
154
+ values = {}
155
+
156
+ raw_values.each do |key, value|
157
+ entry = deserialize_entry(value)
158
+
159
+ unless entry.expired? || entry.mismatched?(normalize_version(keys_to_names[key], options))
160
+ values[keys_to_names[key]] = entry.value
161
+ end
162
+ end
163
+
164
+ values
151
165
  end
152
166
 
153
- private
167
+ # Delete an entry from the cache.
168
+ def delete_entry(key, options)
169
+ rescue_error_with(false) { @data.with { |c| c.delete(key) } }
170
+ end
154
171
 
155
172
  # Memcache keys are binaries. So we need to force their encoding to binary
156
173
  # before applying the regular expression to ensure we are escaping all
157
174
  # characters properly.
158
- def escape_key(key)
159
- key = key.to_s.dup
175
+ def normalize_key(key, options)
176
+ key = super.dup
160
177
  key = key.force_encoding(Encoding::ASCII_8BIT)
161
- key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
162
- key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
178
+ key = key.gsub(ESCAPE_KEY_CHARS) { |match| "%#{match.getbyte(0).to_s(16).upcase}" }
179
+ key = "#{key[0, 213]}:md5:#{ActiveSupport::Digest.hexdigest(key)}" if key.size > 250
163
180
  key
164
181
  end
165
182
 
166
- def deserialize_entry(raw_value)
167
- if raw_value
168
- entry = Marshal.load(raw_value) rescue raw_value
183
+ def deserialize_entry(entry)
184
+ if entry
169
185
  entry.is_a?(Entry) ? entry : Entry.new(entry)
170
- else
171
- nil
172
186
  end
173
187
  end
174
188
 
175
- # Provide support for raw values in the local cache strategy.
176
- module LocalCacheWithRaw # :nodoc:
177
- protected
178
- def read_entry(key, options)
179
- entry = super
180
- if options[:raw] && local_cache && entry
181
- entry = deserialize_entry(entry.value)
182
- end
183
- entry
184
- end
185
-
186
- def write_entry(key, entry, options) # :nodoc:
187
- retval = super
188
- if options[:raw] && local_cache && retval
189
- raw_entry = Entry.new(entry.value.to_s)
190
- raw_entry.expires_at = entry.expires_at
191
- local_cache.write_entry(key, raw_entry, options)
192
- end
193
- retval
194
- end
195
- end
189
+ def rescue_error_with(fallback)
190
+ yield
191
+ rescue Dalli::DalliError => e
192
+ logger.error("DalliError (#{e}): #{e.message}") if logger
193
+ fallback
194
+ end
196
195
  end
197
196
  end
198
197
  end