activesupport 6.1.6.1 → 7.0.3.1

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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +231 -515
  3. data/lib/active_support/actionable_error.rb +1 -1
  4. data/lib/active_support/array_inquirer.rb +0 -2
  5. data/lib/active_support/backtrace_cleaner.rb +2 -2
  6. data/lib/active_support/benchmarkable.rb +2 -2
  7. data/lib/active_support/cache/file_store.rb +15 -9
  8. data/lib/active_support/cache/mem_cache_store.rb +132 -37
  9. data/lib/active_support/cache/memory_store.rb +24 -16
  10. data/lib/active_support/cache/null_store.rb +10 -2
  11. data/lib/active_support/cache/redis_cache_store.rb +47 -72
  12. data/lib/active_support/cache/strategy/local_cache.rb +38 -61
  13. data/lib/active_support/cache.rb +193 -46
  14. data/lib/active_support/callbacks.rb +184 -85
  15. data/lib/active_support/code_generator.rb +65 -0
  16. data/lib/active_support/concern.rb +5 -5
  17. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +2 -4
  18. data/lib/active_support/concurrency/share_lock.rb +2 -2
  19. data/lib/active_support/configurable.rb +8 -5
  20. data/lib/active_support/configuration_file.rb +1 -1
  21. data/lib/active_support/core_ext/array/access.rb +1 -5
  22. data/lib/active_support/core_ext/array/conversions.rb +13 -12
  23. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  24. data/lib/active_support/core_ext/array/grouping.rb +6 -6
  25. data/lib/active_support/core_ext/array/inquiry.rb +2 -2
  26. data/lib/active_support/core_ext/array.rb +1 -0
  27. data/lib/active_support/core_ext/big_decimal/conversions.rb +1 -1
  28. data/lib/active_support/core_ext/class/subclasses.rb +25 -17
  29. data/lib/active_support/core_ext/date/blank.rb +1 -1
  30. data/lib/active_support/core_ext/date/calculations.rb +9 -9
  31. data/lib/active_support/core_ext/date/conversions.rb +14 -14
  32. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  33. data/lib/active_support/core_ext/date.rb +1 -0
  34. data/lib/active_support/core_ext/date_and_time/calculations.rb +4 -4
  35. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  36. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  37. data/lib/active_support/core_ext/date_time/conversions.rb +13 -13
  38. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  39. data/lib/active_support/core_ext/date_time.rb +1 -0
  40. data/lib/active_support/core_ext/digest/uuid.rb +39 -14
  41. data/lib/active_support/core_ext/enumerable.rb +101 -32
  42. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  43. data/lib/active_support/core_ext/hash/conversions.rb +0 -1
  44. data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -3
  45. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  46. data/lib/active_support/core_ext/kernel/reporting.rb +4 -4
  47. data/lib/active_support/core_ext/kernel/singleton_class.rb +1 -1
  48. data/lib/active_support/core_ext/module/attribute_accessors.rb +2 -0
  49. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +19 -10
  50. data/lib/active_support/core_ext/module/delegation.rb +2 -8
  51. data/lib/active_support/core_ext/name_error.rb +2 -8
  52. data/lib/active_support/core_ext/numeric/conversions.rb +80 -77
  53. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  54. data/lib/active_support/core_ext/numeric.rb +1 -0
  55. data/lib/active_support/core_ext/object/acts_like.rb +29 -5
  56. data/lib/active_support/core_ext/object/blank.rb +2 -2
  57. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  58. data/lib/active_support/core_ext/object/duplicable.rb +11 -0
  59. data/lib/active_support/core_ext/object/json.rb +30 -25
  60. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  61. data/lib/active_support/core_ext/object/try.rb +20 -20
  62. data/lib/active_support/core_ext/object/with_options.rb +20 -1
  63. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  64. data/lib/active_support/core_ext/pathname.rb +3 -0
  65. data/lib/active_support/core_ext/range/compare_range.rb +0 -25
  66. data/lib/active_support/core_ext/range/conversions.rb +8 -8
  67. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  68. data/lib/active_support/core_ext/range/each.rb +1 -1
  69. data/lib/active_support/core_ext/range/include_time_with_zone.rb +4 -25
  70. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  71. data/lib/active_support/core_ext/range.rb +1 -1
  72. data/lib/active_support/core_ext/securerandom.rb +1 -1
  73. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  74. data/lib/active_support/core_ext/string/filters.rb +1 -1
  75. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  76. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  77. data/lib/active_support/core_ext/string/output_safety.rb +62 -38
  78. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +0 -8
  79. data/lib/active_support/core_ext/time/calculations.rb +7 -8
  80. data/lib/active_support/core_ext/time/conversions.rb +13 -12
  81. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  82. data/lib/active_support/core_ext/time/zones.rb +7 -22
  83. data/lib/active_support/core_ext/time.rb +1 -0
  84. data/lib/active_support/core_ext/uri.rb +3 -27
  85. data/lib/active_support/core_ext.rb +1 -0
  86. data/lib/active_support/current_attributes.rb +31 -14
  87. data/lib/active_support/dependencies/interlock.rb +10 -18
  88. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  89. data/lib/active_support/dependencies.rb +58 -788
  90. data/lib/active_support/deprecation/behaviors.rb +5 -2
  91. data/lib/active_support/deprecation/method_wrappers.rb +3 -3
  92. data/lib/active_support/deprecation/proxy_wrappers.rb +2 -2
  93. data/lib/active_support/deprecation.rb +2 -2
  94. data/lib/active_support/descendants_tracker.rb +174 -68
  95. data/lib/active_support/digest.rb +4 -4
  96. data/lib/active_support/duration/iso8601_parser.rb +3 -3
  97. data/lib/active_support/duration/iso8601_serializer.rb +9 -1
  98. data/lib/active_support/duration.rb +77 -48
  99. data/lib/active_support/encrypted_configuration.rb +13 -2
  100. data/lib/active_support/encrypted_file.rb +1 -1
  101. data/lib/active_support/environment_inquirer.rb +1 -1
  102. data/lib/active_support/error_reporter.rb +117 -0
  103. data/lib/active_support/evented_file_update_checker.rb +3 -5
  104. data/lib/active_support/execution_context/test_helper.rb +13 -0
  105. data/lib/active_support/execution_context.rb +53 -0
  106. data/lib/active_support/execution_wrapper.rb +30 -11
  107. data/lib/active_support/executor/test_helper.rb +7 -0
  108. data/lib/active_support/fork_tracker.rb +19 -12
  109. data/lib/active_support/gem_version.rb +4 -4
  110. data/lib/active_support/hash_with_indifferent_access.rb +3 -1
  111. data/lib/active_support/html_safe_translation.rb +43 -0
  112. data/lib/active_support/i18n.rb +1 -0
  113. data/lib/active_support/i18n_railtie.rb +1 -1
  114. data/lib/active_support/inflector/inflections.rb +23 -7
  115. data/lib/active_support/inflector/methods.rb +24 -48
  116. data/lib/active_support/inflector/transliterate.rb +1 -1
  117. data/lib/active_support/isolated_execution_state.rb +72 -0
  118. data/lib/active_support/json/encoding.rb +3 -3
  119. data/lib/active_support/key_generator.rb +22 -5
  120. data/lib/active_support/lazy_load_hooks.rb +14 -3
  121. data/lib/active_support/locale/en.yml +1 -1
  122. data/lib/active_support/log_subscriber/test_helper.rb +2 -2
  123. data/lib/active_support/log_subscriber.rb +15 -5
  124. data/lib/active_support/logger.rb +4 -5
  125. data/lib/active_support/logger_thread_safe_level.rb +4 -13
  126. data/lib/active_support/message_encryptor.rb +12 -6
  127. data/lib/active_support/message_verifier.rb +46 -14
  128. data/lib/active_support/messages/metadata.rb +2 -2
  129. data/lib/active_support/multibyte/chars.rb +10 -11
  130. data/lib/active_support/multibyte/unicode.rb +0 -12
  131. data/lib/active_support/multibyte.rb +1 -1
  132. data/lib/active_support/notifications/fanout.rb +91 -65
  133. data/lib/active_support/notifications/instrumenter.rb +32 -15
  134. data/lib/active_support/notifications.rb +17 -23
  135. data/lib/active_support/number_helper/number_converter.rb +1 -3
  136. data/lib/active_support/number_helper/number_to_currency_converter.rb +11 -6
  137. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -1
  138. data/lib/active_support/number_helper/number_to_human_size_converter.rb +1 -1
  139. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -1
  140. data/lib/active_support/number_helper/rounding_helper.rb +1 -5
  141. data/lib/active_support/number_helper.rb +0 -2
  142. data/lib/active_support/option_merger.rb +8 -16
  143. data/lib/active_support/ordered_hash.rb +1 -1
  144. data/lib/active_support/ordered_options.rb +1 -1
  145. data/lib/active_support/parameter_filter.rb +5 -0
  146. data/lib/active_support/per_thread_registry.rb +5 -1
  147. data/lib/active_support/railtie.rb +69 -19
  148. data/lib/active_support/rescuable.rb +4 -4
  149. data/lib/active_support/ruby_features.rb +7 -0
  150. data/lib/active_support/secure_compare_rotator.rb +2 -2
  151. data/lib/active_support/string_inquirer.rb +0 -2
  152. data/lib/active_support/subscriber.rb +7 -18
  153. data/lib/active_support/tagged_logging.rb +16 -1
  154. data/lib/active_support/test_case.rb +9 -21
  155. data/lib/active_support/testing/assertions.rb +35 -5
  156. data/lib/active_support/testing/deprecation.rb +52 -1
  157. data/lib/active_support/testing/isolation.rb +2 -2
  158. data/lib/active_support/testing/method_call_assertions.rb +5 -5
  159. data/lib/active_support/testing/parallelization/server.rb +4 -0
  160. data/lib/active_support/testing/parallelization/worker.rb +3 -0
  161. data/lib/active_support/testing/parallelization.rb +4 -0
  162. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  163. data/lib/active_support/testing/stream.rb +3 -5
  164. data/lib/active_support/testing/tagged_logging.rb +1 -1
  165. data/lib/active_support/testing/time_helpers.rb +13 -2
  166. data/lib/active_support/time_with_zone.rb +58 -17
  167. data/lib/active_support/values/time_zone.rb +33 -14
  168. data/lib/active_support/version.rb +1 -1
  169. data/lib/active_support/xml_mini/jdom.rb +1 -1
  170. data/lib/active_support/xml_mini/libxml.rb +5 -5
  171. data/lib/active_support/xml_mini/libxmlsax.rb +1 -1
  172. data/lib/active_support/xml_mini/nokogiri.rb +4 -4
  173. data/lib/active_support/xml_mini/nokogirisax.rb +1 -1
  174. data/lib/active_support/xml_mini/rexml.rb +1 -1
  175. data/lib/active_support/xml_mini.rb +5 -4
  176. data/lib/active_support.rb +16 -0
  177. metadata +23 -21
  178. data/lib/active_support/core_ext/marshal.rb +0 -26
  179. data/lib/active_support/dependencies/zeitwerk_integration.rb +0 -120
@@ -22,13 +22,24 @@ module ActiveSupport
22
22
 
23
23
  # These options mean something to all cache implementations. Individual cache
24
24
  # implementations may support additional options.
25
- UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :race_condition_ttl, :coder]
25
+ UNIVERSAL_OPTIONS = [:namespace, :compress, :compress_threshold, :expires_in, :expire_in, :expired_in, :race_condition_ttl, :coder, :skip_nil]
26
+
27
+ DEFAULT_COMPRESS_LIMIT = 1.kilobyte
28
+
29
+ # Mapping of canonical option names to aliases that a store will recognize.
30
+ OPTION_ALIASES = {
31
+ expires_in: [:expire_in, :expired_in]
32
+ }.freeze
26
33
 
27
34
  module Strategy
28
35
  autoload :LocalCache, "active_support/cache/strategy/local_cache"
29
36
  end
30
37
 
38
+ @format_version = 6.1
39
+
31
40
  class << self
41
+ attr_accessor :format_version
42
+
32
43
  # Creates a new Store object according to the given options.
33
44
  #
34
45
  # If no arguments are passed to this method, then a new
@@ -130,7 +141,8 @@ module ActiveSupport
130
141
  # Some implementations may not support all methods beyond the basic cache
131
142
  # methods of +fetch+, +write+, +read+, +exist?+, and +delete+.
132
143
  #
133
- # ActiveSupport::Cache::Store can store any serializable Ruby object.
144
+ # ActiveSupport::Cache::Store can store any Ruby object that is supported by
145
+ # its +coder+'s +dump+ and +load+ methods.
134
146
  #
135
147
  # cache = ActiveSupport::Cache::MemoryStore.new
136
148
  #
@@ -138,6 +150,8 @@ module ActiveSupport
138
150
  # cache.write('city', "Duckburgh")
139
151
  # cache.read('city') # => "Duckburgh"
140
152
  #
153
+ # cache.write('not serializable', Proc.new {}) # => TypeError
154
+ #
141
155
  # Keys are always translated into Strings and are case sensitive. When an
142
156
  # object is specified as a key and has a +cache_key+ method defined, this
143
157
  # method will be called to define the key. Otherwise, the +to_param+
@@ -164,8 +178,6 @@ module ActiveSupport
164
178
  # threshold is configurable with the <tt>:compress_threshold</tt> option,
165
179
  # specified in bytes.
166
180
  class Store
167
- DEFAULT_CODER = Marshal
168
-
169
181
  cattr_accessor :logger, instance_writer: true
170
182
 
171
183
  attr_reader :silence, :options
@@ -192,8 +204,12 @@ module ActiveSupport
192
204
  # except for <tt>:namespace</tt> which can be used to set the global
193
205
  # namespace for the cache.
194
206
  def initialize(options = nil)
195
- @options = options ? options.dup : {}
196
- @coder = @options.delete(:coder) { self.class::DEFAULT_CODER } || NullCoder
207
+ @options = options ? normalize_options(options) : {}
208
+ @options[:compress] = true unless @options.key?(:compress)
209
+ @options[:compress_threshold] = DEFAULT_COMPRESS_LIMIT unless @options.key?(:compress_threshold)
210
+
211
+ @coder = @options.delete(:coder) { default_coder } || NullCoder
212
+ @coder_supports_compression = @coder.respond_to?(:dump_compressed)
197
213
  end
198
214
 
199
215
  # Silences the logger.
@@ -255,11 +271,21 @@ module ActiveSupport
255
271
  # All caches support auto-expiring content after a specified number of
256
272
  # seconds. This value can be specified as an option to the constructor
257
273
  # (in which case all entries will be affected), or it can be supplied to
258
- # the +fetch+ or +write+ method to effect just one entry.
274
+ # the +fetch+ or +write+ method to affect just one entry.
275
+ # <tt>:expire_in</tt> and <tt>:expired_in</tt> are aliases for
276
+ # <tt>:expires_in</tt>.
259
277
  #
260
278
  # cache = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes)
261
279
  # cache.write(key, value, expires_in: 1.minute) # Set a lower value for one entry
262
280
  #
281
+ # Setting <tt>:expires_at</tt> will set an absolute expiration time on the cache.
282
+ # All caches support auto-expiring content after a specified number of
283
+ # seconds. This value can only be supplied to the +fetch+ or +write+ method to
284
+ # affect just one entry.
285
+ #
286
+ # cache = ActiveSupport::Cache::MemoryStore.new
287
+ # cache.write(key, value, expires_at: Time.now.at_end_of_hour)
288
+ #
263
289
  # Setting <tt>:version</tt> verifies the cache stored under <tt>name</tt>
264
290
  # is of the same version. nil is returned on mismatches despite contents.
265
291
  # This feature is used to support recyclable cache keys.
@@ -512,6 +538,10 @@ module ActiveSupport
512
538
  end
513
539
  end
514
540
 
541
+ def new_entry(value, options = nil) # :nodoc:
542
+ Entry.new(value, **merged_options(options))
543
+ end
544
+
515
545
  # Deletes all entries with keys matching the pattern.
516
546
  #
517
547
  # Options are passed to the underlying cache implementation.
@@ -559,6 +589,10 @@ module ActiveSupport
559
589
  end
560
590
 
561
591
  private
592
+ def default_coder
593
+ Coders[Cache.format_version]
594
+ end
595
+
562
596
  # Adds the namespace defined in the options to a pattern designed to
563
597
  # match keys. Implementations that support delete_matched should call
564
598
  # this method to translate a pattern that matches names into one that
@@ -590,8 +624,13 @@ module ActiveSupport
590
624
  raise NotImplementedError.new
591
625
  end
592
626
 
593
- def serialize_entry(entry)
594
- @coder.dump(entry)
627
+ def serialize_entry(entry, **options)
628
+ options = merged_options(options)
629
+ if @coder_supports_compression && options[:compress]
630
+ @coder.dump_compressed(entry, options[:compress_threshold] || DEFAULT_COMPRESS_LIMIT)
631
+ else
632
+ @coder.dump(entry)
633
+ end
595
634
  end
596
635
 
597
636
  def deserialize_entry(payload)
@@ -640,6 +679,7 @@ module ActiveSupport
640
679
  # Merges the default options with ones specific to a method call.
641
680
  def merged_options(call_options)
642
681
  if call_options
682
+ call_options = normalize_options(call_options)
643
683
  if options.empty?
644
684
  call_options
645
685
  else
@@ -650,6 +690,18 @@ module ActiveSupport
650
690
  end
651
691
  end
652
692
 
693
+ # Normalize aliased options to their canonical form
694
+ def normalize_options(options)
695
+ options = options.dup
696
+ OPTION_ALIASES.each do |canonical_name, aliases|
697
+ alias_key = aliases.detect { |key| options.key?(key) }
698
+ options[canonical_name] ||= options[alias_key] if alias_key
699
+ options.except!(*aliases)
700
+ end
701
+
702
+ options
703
+ end
704
+
653
705
  # Expands and namespaces the cache key. May be overridden by
654
706
  # cache stores to do additional normalization.
655
707
  def normalize_key(key, options = nil)
@@ -732,7 +784,7 @@ module ActiveSupport
732
784
  if (race_ttl > 0) && (Time.now.to_f - entry.expires_at <= race_ttl)
733
785
  # When an entry has a positive :race_condition_ttl defined, put the stale entry back into the cache
734
786
  # for a brief period while the entry is being recalculated.
735
- entry.expires_at = Time.now + race_ttl
787
+ entry.expires_at = Time.now.to_f + race_ttl
736
788
  write_entry(key, entry, expires_in: race_ttl * 2)
737
789
  else
738
790
  delete_entry(key, **options)
@@ -758,13 +810,93 @@ module ActiveSupport
758
810
  end
759
811
 
760
812
  module NullCoder # :nodoc:
813
+ extend self
814
+
815
+ def dump(entry)
816
+ entry
817
+ end
818
+
819
+ def dump_compressed(entry, threshold)
820
+ entry.compressed(threshold)
821
+ end
822
+
823
+ def load(payload)
824
+ payload
825
+ end
826
+ end
827
+
828
+ module Coders # :nodoc:
829
+ MARK_61 = "\x04\b".b.freeze # The one set by Marshal.
830
+ MARK_70_UNCOMPRESSED = "\x00".b.freeze
831
+ MARK_70_COMPRESSED = "\x01".b.freeze
832
+
761
833
  class << self
834
+ def [](version)
835
+ case version
836
+ when 6.1
837
+ Rails61Coder
838
+ when 7.0
839
+ Rails70Coder
840
+ else
841
+ raise ArgumentError, "Unknown ActiveSupport::Cache.format_version #{Cache.format_version.inspect}"
842
+ end
843
+ end
844
+ end
845
+
846
+ module Loader
847
+ extend self
848
+
762
849
  def load(payload)
763
- payload
850
+ if !payload.is_a?(String)
851
+ ActiveSupport::Cache::Store.logger&.warn %{Payload wasn't a string, was #{payload.class.name} - couldn't unmarshal, so returning nil."}
852
+
853
+ return nil
854
+ elsif payload.start_with?(MARK_70_UNCOMPRESSED)
855
+ members = Marshal.load(payload.byteslice(1..-1))
856
+ elsif payload.start_with?(MARK_70_COMPRESSED)
857
+ members = Marshal.load(Zlib::Inflate.inflate(payload.byteslice(1..-1)))
858
+ elsif payload.start_with?(MARK_61)
859
+ return Marshal.load(payload)
860
+ else
861
+ ActiveSupport::Cache::Store.logger&.warn %{Invalid cache prefix: #{payload.byteslice(0).inspect}, expected "\\x00" or "\\x01"}
862
+
863
+ return nil
864
+ end
865
+ Entry.unpack(members)
764
866
  end
867
+ end
868
+
869
+ module Rails61Coder
870
+ include Loader
871
+ extend self
765
872
 
766
873
  def dump(entry)
767
- entry
874
+ Marshal.dump(entry)
875
+ end
876
+
877
+ def dump_compressed(entry, threshold)
878
+ Marshal.dump(entry.compressed(threshold))
879
+ end
880
+ end
881
+
882
+ module Rails70Coder
883
+ include Loader
884
+ extend self
885
+
886
+ def dump(entry)
887
+ MARK_70_UNCOMPRESSED + Marshal.dump(entry.pack)
888
+ end
889
+
890
+ def dump_compressed(entry, threshold)
891
+ payload = Marshal.dump(entry.pack)
892
+ if payload.bytesize >= threshold
893
+ compressed_payload = Zlib::Deflate.deflate(payload)
894
+ if compressed_payload.bytesize < payload.bytesize
895
+ return MARK_70_COMPRESSED + compressed_payload
896
+ end
897
+ end
898
+
899
+ MARK_70_UNCOMPRESSED + payload
768
900
  end
769
901
  end
770
902
  end
@@ -777,19 +909,22 @@ module ActiveSupport
777
909
  # Since cache entries in most instances will be serialized, the internals of this class are highly optimized
778
910
  # using short instance variable names that are lazily defined.
779
911
  class Entry # :nodoc:
780
- attr_reader :version
912
+ class << self
913
+ def unpack(members)
914
+ new(members[0], expires_at: members[1], version: members[2])
915
+ end
916
+ end
781
917
 
782
- DEFAULT_COMPRESS_LIMIT = 1.kilobyte
918
+ attr_reader :version
783
919
 
784
920
  # Creates a new cache entry for the specified value. Options supported are
785
- # +:compress+, +:compress_threshold+, +:version+ and +:expires_in+.
786
- def initialize(value, compress: true, compress_threshold: DEFAULT_COMPRESS_LIMIT, version: nil, expires_in: nil, **)
921
+ # +:compressed+, +:version+, +:expires_at+ and +:expires_in+.
922
+ def initialize(value, compressed: false, version: nil, expires_in: nil, expires_at: nil, **)
787
923
  @value = value
788
924
  @version = version
789
- @created_at = Time.now.to_f
790
- @expires_in = expires_in && expires_in.to_f
791
-
792
- compress!(compress_threshold) if compress
925
+ @created_at = 0.0
926
+ @expires_in = expires_at&.to_f || expires_in && (expires_in.to_f + Time.now.to_f)
927
+ @compressed = true if compressed
793
928
  end
794
929
 
795
930
  def value
@@ -831,6 +966,38 @@ module ActiveSupport
831
966
  end
832
967
  end
833
968
 
969
+ def compressed? # :nodoc:
970
+ defined?(@compressed)
971
+ end
972
+
973
+ def compressed(compress_threshold)
974
+ return self if compressed?
975
+
976
+ case @value
977
+ when nil, true, false, Numeric
978
+ uncompressed_size = 0
979
+ when String
980
+ uncompressed_size = @value.bytesize
981
+ else
982
+ serialized = Marshal.dump(@value)
983
+ uncompressed_size = serialized.bytesize
984
+ end
985
+
986
+ if uncompressed_size >= compress_threshold
987
+ serialized ||= Marshal.dump(@value)
988
+ compressed = Zlib::Deflate.deflate(serialized)
989
+
990
+ if compressed.bytesize < uncompressed_size
991
+ return Entry.new(compressed, compressed: true, expires_at: expires_at, version: version)
992
+ end
993
+ end
994
+ self
995
+ end
996
+
997
+ def local?
998
+ false
999
+ end
1000
+
834
1001
  # Duplicates the value in a class. This is used by cache implementations that don't natively
835
1002
  # serialize entries to protect against accidental cache modifications.
836
1003
  def dup_value!
@@ -843,33 +1010,13 @@ module ActiveSupport
843
1010
  end
844
1011
  end
845
1012
 
846
- private
847
- def compress!(compress_threshold)
848
- case @value
849
- when nil, true, false, Numeric
850
- uncompressed_size = 0
851
- when String
852
- uncompressed_size = @value.bytesize
853
- else
854
- serialized = Marshal.dump(@value)
855
- uncompressed_size = serialized.bytesize
856
- end
857
-
858
- if uncompressed_size >= compress_threshold
859
- serialized ||= Marshal.dump(@value)
860
- compressed = Zlib::Deflate.deflate(serialized)
861
-
862
- if compressed.bytesize < uncompressed_size
863
- @value = compressed
864
- @compressed = true
865
- end
866
- end
867
- end
868
-
869
- def compressed?
870
- defined?(@compressed)
871
- end
1013
+ def pack
1014
+ members = [value, expires_at, version]
1015
+ members.pop while !members.empty? && members.last.nil?
1016
+ members
1017
+ end
872
1018
 
1019
+ private
873
1020
  def uncompress(value)
874
1021
  Marshal.load(Zlib::Inflate.inflate(value))
875
1022
  end