diff options
Diffstat (limited to 'activesupport/lib/active_support')
11 files changed, 93 insertions, 79 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index a1093a2e23..3847d8b7ae 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -373,6 +373,19 @@ module ActiveSupport results end + # Cache Storage API to write multiple values at once. + def write_multi(hash, options = nil) + options = merged_options(options) + + instrument :write_multi, hash, options do |payload| + entries = hash.each_with_object({}) do |(name, value), memo| + memo[normalize_key(name, options)] = Entry.new(value, options.merge(version: normalize_version(name, options))) + end + + write_multi_entries entries, options + end + end + # Fetches data from the cache, using the given keys. If there is data in # the cache with the given keys, then that data is returned. Otherwise, # the supplied block is called for each key for which there was no data, @@ -397,14 +410,15 @@ module ActiveSupport options = names.extract_options! options = merged_options(options) - results = read_multi(*names, options) - names.each_with_object({}) do |name, memo| - memo[name] = results.fetch(name) do - value = yield name - write(name, value, options) - value + read_multi(*names, options).tap do |results| + writes = {} + + (names - results.keys).each do |name| + results[name] = writes[name] = yield(name) end + + write_multi writes, options end end @@ -485,7 +499,7 @@ module ActiveSupport # The options hash is passed to the underlying cache implementation. # # All implementations may not support this method. - def clear + def clear(options = nil) raise NotImplementedError.new("#{self.class.name} does not support clear") end @@ -521,6 +535,14 @@ module ActiveSupport raise NotImplementedError.new end + # Writes multiple entries to the cache implementation. Subclasses MAY + # implement this method. + def write_multi_entries(hash, options) + hash.each do |key, entry| + write_entry key, entry, options + end + end + # Deletes an entry from the cache implementation. Subclasses must # implement this method. def delete_entry(key, options) diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index d5c8585816..945f50a56e 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -27,7 +27,7 @@ module ActiveSupport # Deletes all items from the cache. In this case it deletes all the entries in the specified # file store directory except for .keep or .gitkeep. Be careful which directory is specified in your # config file when using +FileStore+ because everything in that directory will be deleted. - def clear + def clear(options = nil) root_dirs = exclude_from(cache_path, EXCLUDED_DIRS + GITKEEP_FILES) FileUtils.rm_r(root_dirs.collect { |f| File.join(cache_path, f) }) rescue Errno::ENOENT diff --git a/activesupport/lib/active_support/cache/strategy/local_cache.rb b/activesupport/lib/active_support/cache/strategy/local_cache.rb index 91875a56f5..69b3a93a05 100644 --- a/activesupport/lib/active_support/cache/strategy/local_cache.rb +++ b/activesupport/lib/active_support/cache/strategy/local_cache.rb @@ -44,7 +44,7 @@ module ActiveSupport yield end - def clear + def clear(options = nil) @data.clear end @@ -79,15 +79,15 @@ module ActiveSupport local_cache_key) end - def clear # :nodoc: + def clear(options = nil) # :nodoc: return super unless cache = local_cache - cache.clear + cache.clear(options) super end def cleanup(options = nil) # :nodoc: return super unless cache = local_cache - cache.clear(options) + cache.clear super end diff --git a/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb b/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb index ab80392460..2d45e16546 100644 --- a/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb +++ b/activesupport/lib/active_support/core_ext/date_and_time/compatibility.rb @@ -9,6 +9,6 @@ module DateAndTime # of the receiver. For backwards compatibility we're overriding # this behavior, but new apps will have an initializer that sets # this to true, because the new behavior is preferred. - mattr_accessor(:preserve_timezone, instance_writer: false) { false } + mattr_accessor :preserve_timezone, instance_writer: false, default: false end end diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb index 2c24081eb9..9244cfa157 100644 --- a/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb +++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb @@ -38,13 +38,10 @@ class Module # # Person.new.hair_colors # => NoMethodError # - # - # Also, you can pass a block to set up the attribute with a default value. + # You can set a default value for the attribute. # # module HairColors - # mattr_reader :hair_colors do - # [:brown, :black, :blonde, :red] - # end + # mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red] # end # # class Person @@ -52,8 +49,7 @@ class Module # end # # Person.new.hair_colors # => [:brown, :black, :blonde, :red] - def mattr_reader(*syms) - options = syms.extract_options! + def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil) syms.each do |sym| raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) @@ -64,14 +60,16 @@ class Module end EOS - unless options[:instance_reader] == false || options[:instance_accessor] == false + if instance_reader && instance_accessor class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym} @@#{sym} end EOS end - class_variable_set("@@#{sym}", yield) if block_given? + + sym_default_value = (block_given? && default.nil?) ? yield : default + class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? end end alias :cattr_reader :mattr_reader @@ -107,12 +105,10 @@ class Module # # Person.new.hair_colors = [:blonde, :red] # => NoMethodError # - # Also, you can pass a block to set up the attribute with a default value. + # You can set a default value for the attribute. # # module HairColors - # mattr_writer :hair_colors do - # [:brown, :black, :blonde, :red] - # end + # mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red] # end # # class Person @@ -120,8 +116,7 @@ class Module # end # # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] - def mattr_writer(*syms) - options = syms.extract_options! + def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil) syms.each do |sym| raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym) class_eval(<<-EOS, __FILE__, __LINE__ + 1) @@ -132,14 +127,16 @@ class Module end EOS - unless options[:instance_writer] == false || options[:instance_accessor] == false + if instance_writer && instance_accessor class_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{sym}=(obj) @@#{sym} = obj end EOS end - send("#{sym}=", yield) if block_given? + + sym_default_value = (block_given? && default.nil?) ? yield : default + send("#{sym}=", sym_default_value) unless sym_default_value.nil? end end alias :cattr_writer :mattr_writer @@ -197,12 +194,10 @@ class Module # Person.new.hair_colors = [:brown] # => NoMethodError # Person.new.hair_colors # => NoMethodError # - # Also you can pass a block to set up the attribute with a default value. + # You can set a default value for the attribute. # # module HairColors - # mattr_accessor :hair_colors do - # [:brown, :black, :blonde, :red] - # end + # mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red] # end # # class Person @@ -210,9 +205,9 @@ class Module # end # # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red] - def mattr_accessor(*syms, &blk) - mattr_reader(*syms, &blk) - mattr_writer(*syms) + def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk) + mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, &blk) + mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default) end alias :cattr_accessor :mattr_accessor end diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index e125b657f2..3cd8f3d0ac 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -18,8 +18,7 @@ module ActiveSupport #:nodoc: module Dependencies #:nodoc: extend self - mattr_accessor :interlock - self.interlock = Interlock.new + mattr_accessor :interlock, default: Interlock.new # :doc: @@ -46,46 +45,37 @@ module ActiveSupport #:nodoc: # :nodoc: # Should we turn on Ruby warnings on the first load of dependent files? - mattr_accessor :warnings_on_first_load - self.warnings_on_first_load = false + mattr_accessor :warnings_on_first_load, default: false # All files ever loaded. - mattr_accessor :history - self.history = Set.new + mattr_accessor :history, default: Set.new # All files currently loaded. - mattr_accessor :loaded - self.loaded = Set.new + mattr_accessor :loaded, default: Set.new # Stack of files being loaded. - mattr_accessor :loading - self.loading = [] + mattr_accessor :loading, default: [] # Should we load files or require them? - mattr_accessor :mechanism - self.mechanism = ENV["NO_RELOAD"] ? :require : :load + mattr_accessor :mechanism, default: ENV["NO_RELOAD"] ? :require : :load # The set of directories from which we may automatically load files. Files # under these directories will be reloaded on each request in development mode, # unless the directory also appears in autoload_once_paths. - mattr_accessor :autoload_paths - self.autoload_paths = [] + mattr_accessor :autoload_paths, default: [] # The set of directories from which automatically loaded constants are loaded # only once. All directories in this set must also be present in +autoload_paths+. - mattr_accessor :autoload_once_paths - self.autoload_once_paths = [] + mattr_accessor :autoload_once_paths, default: [] # An array of qualified constant names that have been loaded. Adding a name # to this array will cause it to be unloaded the next time Dependencies are # cleared. - mattr_accessor :autoloaded_constants - self.autoloaded_constants = [] + mattr_accessor :autoloaded_constants, default: [] # An array of constant names that need to be unloaded on every request. Used # to allow arbitrary constants to be marked for unloading. - mattr_accessor :explicitly_unloadable_constants - self.explicitly_unloadable_constants = [] + mattr_accessor :explicitly_unloadable_constants, default: [] # The WatchStack keeps a stack of the modules being watched as files are # loaded. If a file in the process of being loaded (parent.rb) triggers the @@ -175,8 +165,7 @@ module ActiveSupport #:nodoc: end # An internal stack used to record which constants are loaded by any block. - mattr_accessor :constant_watch_stack - self.constant_watch_stack = WatchStack.new + mattr_accessor :constant_watch_stack, default: WatchStack.new # Module includes this module. module ModuleConstMissing #:nodoc: diff --git a/activesupport/lib/active_support/log_subscriber.rb b/activesupport/lib/active_support/log_subscriber.rb index e2c4f33565..e533c6662e 100644 --- a/activesupport/lib/active_support/log_subscriber.rb +++ b/activesupport/lib/active_support/log_subscriber.rb @@ -49,8 +49,7 @@ module ActiveSupport CYAN = "\e[36m" WHITE = "\e[37m" - mattr_accessor :colorize_logging - self.colorize_logging = true + mattr_accessor :colorize_logging, default: true class << self def logger diff --git a/activesupport/lib/active_support/logger_silence.rb b/activesupport/lib/active_support/logger_silence.rb index 632994cf50..9c64afaaca 100644 --- a/activesupport/lib/active_support/logger_silence.rb +++ b/activesupport/lib/active_support/logger_silence.rb @@ -6,8 +6,7 @@ module LoggerSilence extend ActiveSupport::Concern included do - cattr_accessor :silencer - self.silencer = true + cattr_accessor :silencer, default: true end # Silences the logger for the duration of the block. diff --git a/activesupport/lib/active_support/message_encryptor.rb b/activesupport/lib/active_support/message_encryptor.rb index 726e1464ad..e576766c64 100644 --- a/activesupport/lib/active_support/message_encryptor.rb +++ b/activesupport/lib/active_support/message_encryptor.rb @@ -19,7 +19,17 @@ module ActiveSupport # encrypted_data = crypt.encrypt_and_sign('my secret data') # => "NlFBTTMwOUV5UlA1QlNEN2xkY2d6eThYWWh..." # crypt.decrypt_and_verify(encrypted_data) # => "my secret data" class MessageEncryptor - DEFAULT_CIPHER = "aes-256-cbc" + class << self + attr_accessor :use_authenticated_message_encryption #:nodoc: + + def default_cipher #:nodoc: + if use_authenticated_message_encryption + "aes-256-gcm" + else + "aes-256-cbc" + end + end + end module NullSerializer #:nodoc: def self.load(value) @@ -45,7 +55,7 @@ module ActiveSupport OpenSSLCipherError = OpenSSL::Cipher::CipherError # Initialize a new MessageEncryptor. +secret+ must be at least as long as - # the cipher key size. For the default 'aes-256-cbc' cipher, this is 256 + # the cipher key size. For the default 'aes-256-gcm' cipher, this is 256 # bits. If you are using a user-entered secret, you can generate a suitable # key by using <tt>ActiveSupport::KeyGenerator</tt> or a similar key # derivation function. @@ -57,7 +67,7 @@ module ActiveSupport # # Options: # * <tt>:cipher</tt> - Cipher to use. Can be any cipher returned by - # <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-cbc'. + # <tt>OpenSSL::Cipher.ciphers</tt>. Default is 'aes-256-gcm'. # * <tt>:digest</tt> - String of digest to use for signing. Default is # +SHA1+. Ignored when using an AEAD cipher like 'aes-256-gcm'. # * <tt>:serializer</tt> - Object serializer to use. Default is +Marshal+. @@ -66,7 +76,7 @@ module ActiveSupport sign_secret = signature_key_or_options.first @secret = secret @sign_secret = sign_secret - @cipher = options[:cipher] || DEFAULT_CIPHER + @cipher = options[:cipher] || self.class.default_cipher @digest = options[:digest] || "SHA1" unless aead_mode? @verifier = resolve_verifier @serializer = options[:serializer] || Marshal @@ -85,7 +95,7 @@ module ActiveSupport end # Given a cipher, returns the key length of the cipher to help generate the key of desired size - def self.key_len(cipher = DEFAULT_CIPHER) + def self.key_len(cipher = default_cipher) OpenSSL::Cipher.new(cipher).key_len end diff --git a/activesupport/lib/active_support/number_helper/rounding_helper.rb b/activesupport/lib/active_support/number_helper/rounding_helper.rb index d9644df17d..63b48444a6 100644 --- a/activesupport/lib/active_support/number_helper/rounding_helper.rb +++ b/activesupport/lib/active_support/number_helper/rounding_helper.rb @@ -40,11 +40,11 @@ module ActiveSupport def convert_to_decimal(number) case number when Float, String - number = BigDecimal(number.to_s) + BigDecimal(number.to_s) when Rational - number = BigDecimal(number, digit_count(number.to_i) + precision) + BigDecimal(number, digit_count(number.to_i) + precision) else - number = number.to_d + number.to_d end end diff --git a/activesupport/lib/active_support/railtie.rb b/activesupport/lib/active_support/railtie.rb index 1b4ecf4d72..45bc51311b 100644 --- a/activesupport/lib/active_support/railtie.rb +++ b/activesupport/lib/active_support/railtie.rb @@ -7,6 +7,13 @@ module ActiveSupport config.eager_load_namespaces << ActiveSupport + initializer "active_support.set_authenticated_message_encryption" do |app| + if app.config.active_support.respond_to?(:use_authenticated_message_encryption) + ActiveSupport::MessageEncryptor.use_authenticated_message_encryption = + app.config.active_support.use_authenticated_message_encryption + end + end + initializer "active_support.reset_all_current_attributes_instances" do |app| app.reloader.before_class_unload { ActiveSupport::CurrentAttributes.clear_all } app.executor.to_run { ActiveSupport::CurrentAttributes.reset_all } @@ -28,14 +35,7 @@ module ActiveSupport raise e.exception "tzinfo-data is not present. Please add gem 'tzinfo-data' to your Gemfile and run bundle install" end require "active_support/core_ext/time/zones" - zone_default = Time.find_zone!(app.config.time_zone) - - unless zone_default - raise "Value assigned to config.time_zone not recognized. " \ - 'Run "rake time:zones:all" for a time zone names list.' - end - - Time.zone_default = zone_default + Time.zone_default = Time.find_zone!(app.config.time_zone) end # Sets the default week start |