diff options
author | Pratik Naik <pratiknaik@gmail.com> | 2008-08-14 16:31:14 +0100 |
---|---|---|
committer | Pratik Naik <pratiknaik@gmail.com> | 2008-08-14 16:31:14 +0100 |
commit | 2ebe8d275efa53af967b09ad66dab68acc1aed98 (patch) | |
tree | b0b3e42c277b213788b55558aef3579f4e242300 /activesupport/lib | |
parent | 73ef94e9675ef6db85f18f1e3c70bf6ddfc1260a (diff) | |
parent | 8cb14ee1203c9ed380c4b192e8730757a52d43cb (diff) | |
download | rails-2ebe8d275efa53af967b09ad66dab68acc1aed98.tar.gz rails-2ebe8d275efa53af967b09ad66dab68acc1aed98.tar.bz2 rails-2ebe8d275efa53af967b09ad66dab68acc1aed98.zip |
Merge commit 'mainstream/master'
Conflicts:
actionpack/lib/action_controller/request.rb
actionpack/lib/action_controller/resources.rb
Diffstat (limited to 'activesupport/lib')
8 files changed, 129 insertions, 66 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 5a064f8bea..95eae3a77e 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -39,10 +39,6 @@ module ActiveSupport class Store cattr_accessor :logger - def threadsafe! - extend ThreadSafety - end - def silence! @silence = true self @@ -115,20 +111,6 @@ module ActiveSupport logger.debug("Cache #{operation}: #{key}#{options ? " (#{options.inspect})" : ""}") if logger && !@silence && !@logger_off end end - - module ThreadSafety #:nodoc: - def self.extended(object) #:nodoc: - object.instance_variable_set(:@mutex, Mutex.new) - end - - %w(read write delete delete_matched exist? increment decrement).each do |method| - module_eval <<-EOS, __FILE__, __LINE__ - def #{method}(*args) - @mutex.synchronize { super } - end - EOS - end - end end end diff --git a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb index 9470ac9f66..0bff6cf9ad 100644 --- a/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb +++ b/activesupport/lib/active_support/cache/compressed_mem_cache_store.rb @@ -1,14 +1,14 @@ module ActiveSupport module Cache class CompressedMemCacheStore < MemCacheStore - def read(name, options = {}) - if value = super(name, options.merge(:raw => true)) + def read(name, options = nil) + if value = super(name, (options || {}).merge(:raw => true)) Marshal.load(ActiveSupport::Gzip.decompress(value)) end end - def write(name, value, options = {}) - super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), options.merge(:raw => true)) + def write(name, value, options = nil) + super(name, ActiveSupport::Gzip.compress(Marshal.dump(value)), (options || {}).merge(:raw => true)) end end end diff --git a/activesupport/lib/active_support/cache/file_store.rb b/activesupport/lib/active_support/cache/file_store.rb index 5b771b1da0..437679cc05 100644 --- a/activesupport/lib/active_support/cache/file_store.rb +++ b/activesupport/lib/active_support/cache/file_store.rb @@ -9,13 +9,13 @@ module ActiveSupport def read(name, options = nil) super - File.open(real_file_path(name), 'rb') { |f| f.read } rescue nil + File.open(real_file_path(name), 'rb') { |f| Marshal.load(f) } rescue nil end def write(name, value, options = nil) super ensure_cache_path(File.dirname(real_file_path(name))) - File.open(real_file_path(name), "wb+") { |f| f.write(value) } + File.atomic_write(real_file_path(name), cache_path) { |f| Marshal.dump(value, f) } rescue => e RAILS_DEFAULT_LOGGER.error "Couldn't create cache directory: #{name} (#{e.message})" if RAILS_DEFAULT_LOGGER end diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb index 6f114273e4..a44f877414 100644 --- a/activesupport/lib/active_support/cache/memory_store.rb +++ b/activesupport/lib/active_support/cache/memory_store.rb @@ -3,6 +3,13 @@ module ActiveSupport class MemoryStore < Store def initialize @data = {} + @mutex = Mutex.new + end + + def fetch(key, options = {}) + @mutex.synchronize do + super + end end def read(name, options = nil) @@ -16,23 +23,32 @@ module ActiveSupport end def delete(name, options = nil) - super @data.delete(name) end def delete_matched(matcher, options = nil) - super @data.delete_if { |k,v| k =~ matcher } end def exist?(name,options = nil) - super @data.has_key?(name) end + def increment(key, amount = 1) + @mutex.synchronize do + super + end + end + + def decrement(key, amount = 1) + @mutex.synchronize do + super + end + end + def clear @data.clear end end end -end
\ No newline at end of file +end diff --git a/activesupport/lib/active_support/core_ext/file.rb b/activesupport/lib/active_support/core_ext/file.rb index 45d93b220f..e03f8ac44e 100644 --- a/activesupport/lib/active_support/core_ext/file.rb +++ b/activesupport/lib/active_support/core_ext/file.rb @@ -1,21 +1,5 @@ -require 'tempfile' +require 'active_support/core_ext/file/atomic' -# Write to a file atomically. Useful for situations where you don't -# want other processes or threads to see half-written files. -# -# File.atomic_write("important.file") do |file| -# file.write("hello") -# end -# -# If your temp directory is not on the same filesystem as the file you're -# trying to write, you can provide a different temporary directory. -# -# File.atomic_write("/data/something.important", "/data/tmp") do |f| -# file.write("hello") -# end -def File.atomic_write(file_name, temp_dir = Dir.tmpdir) - temp_file = Tempfile.new(File.basename(file_name), temp_dir) - yield temp_file - temp_file.close - File.rename(temp_file.path, file_name) -end
\ No newline at end of file +class File #:nodoc: + extend ActiveSupport::CoreExtensions::File::Atomic +end diff --git a/activesupport/lib/active_support/core_ext/file/atomic.rb b/activesupport/lib/active_support/core_ext/file/atomic.rb new file mode 100644 index 0000000000..4d3cf5423f --- /dev/null +++ b/activesupport/lib/active_support/core_ext/file/atomic.rb @@ -0,0 +1,46 @@ +require 'tempfile' + +module ActiveSupport #:nodoc: + module CoreExtensions #:nodoc: + module File #:nodoc: + module Atomic + # Write to a file atomically. Useful for situations where you don't + # want other processes or threads to see half-written files. + # + # File.atomic_write("important.file") do |file| + # file.write("hello") + # end + # + # If your temp directory is not on the same filesystem as the file you're + # trying to write, you can provide a different temporary directory. + # + # File.atomic_write("/data/something.important", "/data/tmp") do |f| + # file.write("hello") + # end + def atomic_write(file_name, temp_dir = Dir.tmpdir) + temp_file = Tempfile.new(basename(file_name), temp_dir) + yield temp_file + temp_file.close + + begin + # Get original file permissions + old_stat = stat(file_name) + rescue Errno::ENOENT + # No old permissions, write a temp file to determine the defaults + check_name = ".permissions_check.#{Thread.current.object_id}.#{Process.pid}.#{rand(1000000)}" + new(check_name, "w") + old_stat = stat(check_name) + unlink(check_name) + end + + # Overwrite original file with temp file + rename(temp_file.path, file_name) + + # Set correct permissions on new file + chown(old_stat.uid, old_stat.gid, file_name) + chmod(old_stat.mode, file_name) + end + end + end + end +end diff --git a/activesupport/lib/active_support/inflector.rb b/activesupport/lib/active_support/inflector.rb index 6651569d33..c2738b39fc 100644 --- a/activesupport/lib/active_support/inflector.rb +++ b/activesupport/lib/active_support/inflector.rb @@ -291,11 +291,14 @@ module ActiveSupport # NameError is raised when the name is not in CamelCase or the constant is # unknown. def constantize(camel_cased_word) - unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word - raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!" - end + names = camel_cased_word.split('::') + names.shift if names.empty? || names.first.empty? - Object.module_eval("::#{$1}", __FILE__, __LINE__) + constant = Object + names.each do |name| + constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name) + end + constant end # Turns a number into an ordinal string used to denote the position in an @@ -326,4 +329,4 @@ require 'active_support/inflections' require 'active_support/core_ext/string/inflections' unless String.included_modules.include?(ActiveSupport::CoreExtensions::String::Inflections) String.send :include, ActiveSupport::CoreExtensions::String::Inflections -end
\ No newline at end of file +end diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb index 23dd96e4df..6506238ac0 100644 --- a/activesupport/lib/active_support/memoizable.rb +++ b/activesupport/lib/active_support/memoizable.rb @@ -10,18 +10,37 @@ module ActiveSupport end def freeze_with_memoizable - methods.each do |method| - __send__($1) if method.to_s =~ /^_unmemoized_(.*)/ - end unless frozen? - + memoize_all unless frozen? freeze_without_memoizable end + + def memoize_all + methods.each do |m| + if m.to_s =~ /^_unmemoized_(.*)/ + if method(m).arity == 0 + __send__($1) + else + ivar = :"@_memoized_#{$1}" + instance_variable_set(ivar, {}) + end + end + end + end + + def unmemoize_all + methods.each do |m| + if m.to_s =~ /^_unmemoized_(.*)/ + ivar = :"@_memoized_#{$1}" + instance_variable_get(ivar).clear if instance_variable_defined?(ivar) + end + end + end end def memoize(*symbols) symbols.each do |symbol| - original_method = "_unmemoized_#{symbol}" - memoized_ivar = "@_memoized_#{symbol}" + original_method = :"_unmemoized_#{symbol}" + memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}" class_eval <<-EOS, __FILE__, __LINE__ include Freezable @@ -29,14 +48,27 @@ module ActiveSupport raise "Already memoized #{symbol}" if method_defined?(:#{original_method}) alias #{original_method} #{symbol} - def #{symbol}(*args) - #{memoized_ivar} ||= {} - reload = args.pop if args.last == true || args.last == :reload + if instance_method(:#{symbol}).arity == 0 + def #{symbol}(reload = false) + if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty? + #{memoized_ivar} = [#{original_method}.freeze] + end + #{memoized_ivar}[0] + end + else + def #{symbol}(*args) + #{memoized_ivar} ||= {} unless frozen? + reload = args.pop if args.last == true || args.last == :reload - if !reload && #{memoized_ivar} && #{memoized_ivar}.has_key?(args) - #{memoized_ivar}[args] - else - #{memoized_ivar}[args] = #{original_method}(*args).freeze + if #{memoized_ivar} + if !reload && #{memoized_ivar}.has_key?(args) + #{memoized_ivar}[args] + elsif #{memoized_ivar} + #{memoized_ivar}[args] = #{original_method}(*args).freeze + end + else + #{original_method}(*args) + end end end EOS |