aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support
diff options
context:
space:
mode:
authorSven Fuchs <svenfuchs@artweb-design.de>2008-08-21 19:04:39 +0200
committerSven Fuchs <svenfuchs@artweb-design.de>2008-08-21 19:04:39 +0200
commitaad429a46e3017fa7ca73f58428693e821be42b6 (patch)
treef749e0cdeab20c7f4be37ff49e064705f17cdfa5 /activesupport/lib/active_support
parentcf6840773b4f5046151f4d28c286069aabaafa10 (diff)
parent8622787f8748434b4ceb2b925a35b17a38e1f2d6 (diff)
downloadrails-aad429a46e3017fa7ca73f58428693e821be42b6.tar.gz
rails-aad429a46e3017fa7ca73f58428693e821be42b6.tar.bz2
rails-aad429a46e3017fa7ca73f58428693e821be42b6.zip
Merge branch 'master' into i18n
Diffstat (limited to 'activesupport/lib/active_support')
-rw-r--r--activesupport/lib/active_support/buffered_logger.rb19
-rw-r--r--activesupport/lib/active_support/cache/compressed_mem_cache_store.rb8
-rw-r--r--activesupport/lib/active_support/cache/file_store.rb8
-rw-r--r--activesupport/lib/active_support/cache/memory_store.rb36
-rw-r--r--activesupport/lib/active_support/callbacks.rb21
-rw-r--r--activesupport/lib/active_support/core_ext/kernel/debugger.rb8
-rw-r--r--activesupport/lib/active_support/dependencies.rb10
-rw-r--r--activesupport/lib/active_support/memoizable.rb51
-rw-r--r--activesupport/lib/active_support/testing/performance.rb66
-rw-r--r--activesupport/lib/active_support/typed_array.rb31
10 files changed, 161 insertions, 97 deletions
diff --git a/activesupport/lib/active_support/buffered_logger.rb b/activesupport/lib/active_support/buffered_logger.rb
index cedc1afe7f..6553d72b4f 100644
--- a/activesupport/lib/active_support/buffered_logger.rb
+++ b/activesupport/lib/active_support/buffered_logger.rb
@@ -33,11 +33,10 @@ module ActiveSupport
attr_accessor :level
attr_reader :auto_flushing
- attr_reader :buffer
def initialize(log, level = DEBUG)
@level = level
- @buffer = []
+ @buffer = {}
@auto_flushing = 1
@guard = Mutex.new
@@ -60,9 +59,7 @@ module ActiveSupport
# If a newline is necessary then create a new message ending with a newline.
# Ensures that the original message is not mutated.
message = "#{message}\n" unless message[-1] == ?\n
- @guard.synchronize do
- buffer << message
- end
+ buffer << message
auto_flush
message
end
@@ -96,8 +93,8 @@ module ActiveSupport
def flush
@guard.synchronize do
unless buffer.empty?
- old_buffer = @buffer
- @buffer = []
+ old_buffer = buffer
+ clear_buffer
@log.write(old_buffer.join)
end
end
@@ -113,5 +110,13 @@ module ActiveSupport
def auto_flush
flush if buffer.size >= @auto_flushing
end
+
+ def buffer
+ @buffer[Thread.current] ||= []
+ end
+
+ def clear_buffer
+ @buffer[Thread.current] = []
+ 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 7b6ca39091..659bde64f0 100644
--- a/activesupport/lib/active_support/cache/file_store.rb
+++ b/activesupport/lib/active_support/cache/file_store.rb
@@ -9,15 +9,15 @@ 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.atomic_write(real_file_path(name), cache_path) { |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
+ logger.error "Couldn't create cache directory: #{name} (#{e.message})" if logger
end
def delete(name, options = nil)
@@ -67,4 +67,4 @@ module ActiveSupport
end
end
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/cache/memory_store.rb b/activesupport/lib/active_support/cache/memory_store.rb
index a44f877414..f3e4b8c13b 100644
--- a/activesupport/lib/active_support/cache/memory_store.rb
+++ b/activesupport/lib/active_support/cache/memory_store.rb
@@ -3,51 +3,63 @@ module ActiveSupport
class MemoryStore < Store
def initialize
@data = {}
- @mutex = Mutex.new
+ @guard = Monitor.new
end
def fetch(key, options = {})
- @mutex.synchronize do
+ @guard.synchronize do
super
end
end
def read(name, options = nil)
- super
- @data[name]
+ @guard.synchronize do
+ super
+ @data[name]
+ end
end
def write(name, value, options = nil)
- super
- @data[name] = value
+ @guard.synchronize do
+ super
+ @data[name] = value.freeze
+ end
end
def delete(name, options = nil)
- @data.delete(name)
+ @guard.synchronize do
+ @data.delete(name)
+ end
end
def delete_matched(matcher, options = nil)
- @data.delete_if { |k,v| k =~ matcher }
+ @guard.synchronize do
+ @data.delete_if { |k,v| k =~ matcher }
+ end
end
def exist?(name,options = nil)
- @data.has_key?(name)
+ @guard.synchronize do
+ @data.has_key?(name)
+ end
end
def increment(key, amount = 1)
- @mutex.synchronize do
+ @guard.synchronize do
super
end
end
def decrement(key, amount = 1)
- @mutex.synchronize do
+ @guard.synchronize do
super
end
end
def clear
- @data.clear
+ @guard.synchronize do
+ @data.clear
+ end
end
end
end
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 9c59b7ac76..7b905930bb 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -96,15 +96,12 @@ module ActiveSupport
end
end
- def |(chain)
- if chain.is_a?(CallbackChain)
- chain.each { |callback| self | callback }
+ # TODO: Decompose into more Array like behavior
+ def replace_or_append!(chain)
+ if index = index(chain)
+ self[index] = chain
else
- if (found_callback = find(chain)) && (index = index(chain))
- self[index] = chain
- else
- self << chain
- end
+ self << chain
end
self
end
@@ -157,6 +154,14 @@ module ActiveSupport
self.class.new(@kind, @method, @options.dup)
end
+ def hash
+ if @identifier
+ @identifier.hash
+ else
+ @method.hash
+ end
+ end
+
def call(*args, &block)
evaluate_method(method, *args, &block) if should_run_callback?(*args)
rescue LocalJumpError
diff --git a/activesupport/lib/active_support/core_ext/kernel/debugger.rb b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
index c74d6cf884..4007a647be 100644
--- a/activesupport/lib/active_support/core_ext/kernel/debugger.rb
+++ b/activesupport/lib/active_support/core_ext/kernel/debugger.rb
@@ -2,12 +2,12 @@ module Kernel
unless respond_to?(:debugger)
# Starts a debugging session if ruby-debug has been loaded (call script/server --debugger to do load it).
def debugger
- RAILS_DEFAULT_LOGGER.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
+ Rails.logger.info "\n***** Debugger requested, but was not available: Start server with --debugger to enable *****\n"
end
end
-
+
def breakpoint
- RAILS_DEFAULT_LOGGER.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
+ Rails.logger.info "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
debugger
end
-end \ No newline at end of file
+end
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index a3f5f799a2..3d871eec11 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -39,6 +39,10 @@ module ActiveSupport #:nodoc:
mattr_accessor :explicitly_unloadable_constants
self.explicitly_unloadable_constants = []
+ # The logger is used for generating information on the action run-time (including benchmarking) if available.
+ # Can be set to nil for no logging. Compatible with both Ruby's own Logger and Log4r loggers.
+ mattr_accessor :logger
+
# Set to true to enable logging of const_missing and file loads
mattr_accessor :log_activity
self.log_activity = false
@@ -584,7 +588,7 @@ module ActiveSupport #:nodoc:
protected
def log_call(*args)
- if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
+ if logger && log_activity
arg_str = args.collect { |arg| arg.inspect } * ', '
/in `([a-z_\?\!]+)'/ =~ caller(1).first
selector = $1 || '<unknown>'
@@ -593,8 +597,8 @@ module ActiveSupport #:nodoc:
end
def log(msg)
- if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER && log_activity
- RAILS_DEFAULT_LOGGER.debug "Dependencies: #{msg}"
+ if logger && log_activity
+ logger.debug "Dependencies: #{msg}"
end
end
end
diff --git a/activesupport/lib/active_support/memoizable.rb b/activesupport/lib/active_support/memoizable.rb
index e6049d9496..6506238ac0 100644
--- a/activesupport/lib/active_support/memoizable.rb
+++ b/activesupport/lib/active_support/memoizable.rb
@@ -10,25 +10,37 @@ module ActiveSupport
end
def freeze_with_memoizable
- unless frozen?
- methods.each do |method|
- if method.to_s =~ /^_unmemoized_(.*)/
- begin
- __send__($1)
- rescue ArgumentError
- end
+ 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
- freeze_without_memoizable
+ 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.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
+ original_method = :"_unmemoized_#{symbol}"
+ memoized_ivar = :"@_memoized_#{symbol.to_s.sub(/\?\Z/, '_query').sub(/!\Z/, '_bang')}"
class_eval <<-EOS, __FILE__, __LINE__
include Freezable
@@ -38,21 +50,24 @@ module ActiveSupport
if instance_method(:#{symbol}).arity == 0
def #{symbol}(reload = false)
- if !reload && defined? #{memoized_ivar}
- #{memoized_ivar}
- else
- #{memoized_ivar} = #{original_method}.freeze
+ if reload || !defined?(#{memoized_ivar}) || #{memoized_ivar}.empty?
+ #{memoized_ivar} = [#{original_method}.freeze]
end
+ #{memoized_ivar}[0]
end
else
def #{symbol}(*args)
- #{memoized_ivar} ||= {}
+ #{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]
+ 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
- #{memoized_ivar}[args] = #{original_method}(*args).freeze
+ #{original_method}(*args)
end
end
end
diff --git a/activesupport/lib/active_support/testing/performance.rb b/activesupport/lib/active_support/testing/performance.rb
index 70a7f84023..3ad7289571 100644
--- a/activesupport/lib/active_support/testing/performance.rb
+++ b/activesupport/lib/active_support/testing/performance.rb
@@ -25,7 +25,7 @@ module ActiveSupport
def self.included(base)
base.class_inheritable_hash :profile_options
- base.profile_options = DEFAULTS.dup
+ base.profile_options = DEFAULTS
end
def full_test_name
@@ -34,6 +34,7 @@ module ActiveSupport
def run(result)
return if method_name =~ /^default_test$/
+ self.profile_options ||= DEFAULTS
yield(self.class::STARTED, name)
@_result = result
@@ -43,8 +44,6 @@ module ActiveSupport
if klass = Metrics[metric_name.to_sym]
run_profile(klass.new)
result.add_run
- else
- $stderr.puts '%20s: unsupported' % metric_name.to_s
end
end
@@ -164,7 +163,14 @@ module ActiveSupport
end
class Profiler < Performer
+ def initialize(*args)
+ super
+ @supported = @metric.measure_mode rescue false
+ end
+
def run
+ return unless @supported
+
RubyProf.measure_mode = @metric.measure_mode
RubyProf.start
RubyProf.pause
@@ -173,7 +179,17 @@ module ActiveSupport
@total = @data.threads.values.sum(0) { |method_infos| method_infos.sort.last.total_time }
end
+ def report
+ if @supported
+ super
+ else
+ '%20s: unsupported' % @metric.name
+ end
+ end
+
def record
+ return unless @supported
+
klasses = profile_options[:formats].map { |f| RubyProf.const_get("#{f.to_s.camelize}Printer") }.compact
klasses.each do |klass|
@@ -202,8 +218,7 @@ module ActiveSupport
module Metrics
def self.[](name)
- klass = const_get(name.to_s.camelize)
- klass if klass::Mode
+ const_get(name.to_s.camelize)
rescue NameError
nil
end
@@ -250,6 +265,16 @@ module ActiveSupport
ensure
GC.disable_stats
end
+ elsif defined?(GC::Profiler)
+ def with_gc_stats
+ GC.start
+ GC.disable
+ GC::Profiler.enable
+ yield
+ ensure
+ GC::Profiler.disable
+ GC.enable
+ end
else
def with_gc_stats
yield
@@ -310,7 +335,7 @@ module ActiveSupport
RubyProf.measure_memory / 1024.0
end
- # Ruby 1.8 + adymo patch
+ # Ruby 1.8 + railsbench patch
elsif GC.respond_to?(:allocated_size)
def measure
GC.allocated_size / 1024.0
@@ -322,11 +347,27 @@ module ActiveSupport
GC.heap_info['heap_current_memory'] / 1024.0
end
+ # Ruby 1.9 with total_malloc_allocated_size patch
+ elsif GC.respond_to?(:malloc_total_allocated_size)
+ def measure
+ GC.total_malloc_allocated_size / 1024.0
+ end
+
# Ruby 1.9 unpatched
elsif GC.respond_to?(:malloc_allocated_size)
def measure
GC.malloc_allocated_size / 1024.0
end
+
+ # Ruby 1.9 + GC profiler patch
+ elsif defined?(GC::Profiler)
+ def measure
+ GC.enable
+ GC.start
+ kb = GC::Profiler.data.last[:HEAP_USE_SIZE] / 1024.0
+ GC.disable
+ kb
+ end
end
def format(measurement)
@@ -341,10 +382,23 @@ module ActiveSupport
def measure
RubyProf.measure_allocations
end
+
+ # Ruby 1.8 + railsbench patch
elsif ObjectSpace.respond_to?(:allocated_objects)
def measure
ObjectSpace.allocated_objects
end
+
+ # Ruby 1.9 + GC profiler patch
+ elsif defined?(GC::Profiler)
+ def measure
+ GC.enable
+ GC.start
+ last = GC::Profiler.data.last
+ count = last[:HEAP_LIVE_OBJECTS] + last[:HEAP_FREE_OBJECTS]
+ GC.disable
+ count
+ end
end
def format(measurement)
diff --git a/activesupport/lib/active_support/typed_array.rb b/activesupport/lib/active_support/typed_array.rb
deleted file mode 100644
index 1a4d8a8faf..0000000000
--- a/activesupport/lib/active_support/typed_array.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-module ActiveSupport
- class TypedArray < Array
- def self.type_cast(obj)
- obj
- end
-
- def initialize(*args)
- super(*args).map! { |obj| self.class.type_cast(obj) }
- end
-
- def <<(obj)
- super(self.class.type_cast(obj))
- end
-
- def concat(array)
- super(array.map! { |obj| self.class.type_cast(obj) })
- end
-
- def insert(index, obj)
- super(index, self.class.type_cast(obj))
- end
-
- def push(*objs)
- super(*objs.map { |obj| self.class.type_cast(obj) })
- end
-
- def unshift(*objs)
- super(*objs.map { |obj| self.class.type_cast(obj) })
- end
- end
-end