aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/dependencies.rb
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2014-09-30 01:32:42 +0930
committerMatthew Draper <matthew@trebex.net>2015-07-09 02:23:23 +0930
commitc37d47e30897762145835e66ae752cce924af01d (patch)
tree1b615adf6030b9d77557c88a51497c432a2c58a8 /activesupport/lib/active_support/dependencies.rb
parentc2b5aa041b04e65475dd3ebb9f33a68b26e25895 (diff)
downloadrails-c37d47e30897762145835e66ae752cce924af01d.tar.gz
rails-c37d47e30897762145835e66ae752cce924af01d.tar.bz2
rails-c37d47e30897762145835e66ae752cce924af01d.zip
Soften the lock requirements when eager_load is disabled
We don't need to fully disable concurrent requests: just ensure that loads are performed in isolation.
Diffstat (limited to 'activesupport/lib/active_support/dependencies.rb')
-rw-r--r--activesupport/lib/active_support/dependencies.rb81
1 files changed, 47 insertions, 34 deletions
diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb
index 664cc15a29..2a0e06495f 100644
--- a/activesupport/lib/active_support/dependencies.rb
+++ b/activesupport/lib/active_support/dependencies.rb
@@ -12,12 +12,16 @@ require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/load_error'
require 'active_support/core_ext/name_error'
require 'active_support/core_ext/string/starts_ends_with'
+require "active_support/dependencies/interlock"
require 'active_support/inflector'
module ActiveSupport #:nodoc:
module Dependencies #:nodoc:
extend self
+ mattr_accessor :interlock
+ self.interlock = Interlock.new
+
# 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
@@ -234,10 +238,12 @@ module ActiveSupport #:nodoc:
end
def load_dependency(file)
- if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
- Dependencies.new_constants_in(Object) { yield }
- else
- yield
+ Dependencies.interlock.loading do
+ if Dependencies.load? && ActiveSupport::Dependencies.constant_watch_stack.watching?
+ Dependencies.new_constants_in(Object) { yield }
+ else
+ yield
+ end
end
rescue Exception => exception # errors from loading file
exception.blame_file! file if exception.respond_to? :blame_file!
@@ -325,9 +331,11 @@ module ActiveSupport #:nodoc:
def clear
log_call
- loaded.clear
- loading.clear
- remove_unloadable_constants!
+ Dependencies.interlock.loading do
+ loaded.clear
+ loading.clear
+ remove_unloadable_constants!
+ end
end
def require_or_load(file_name, const_path = nil)
@@ -336,39 +344,44 @@ module ActiveSupport #:nodoc:
expanded = File.expand_path(file_name)
return if loaded.include?(expanded)
- # Record that we've seen this file *before* loading it to avoid an
- # infinite loop with mutual dependencies.
- loaded << expanded
- loading << expanded
-
- begin
- if load?
- log "loading #{file_name}"
+ Dependencies.interlock.loading do
+ # Maybe it got loaded while we were waiting for our lock:
+ return if loaded.include?(expanded)
- # Enable warnings if this file has not been loaded before and
- # warnings_on_first_load is set.
- load_args = ["#{file_name}.rb"]
- load_args << const_path unless const_path.nil?
+ # Record that we've seen this file *before* loading it to avoid an
+ # infinite loop with mutual dependencies.
+ loaded << expanded
+ loading << expanded
- if !warnings_on_first_load or history.include?(expanded)
- result = load_file(*load_args)
+ begin
+ if load?
+ log "loading #{file_name}"
+
+ # Enable warnings if this file has not been loaded before and
+ # warnings_on_first_load is set.
+ load_args = ["#{file_name}.rb"]
+ load_args << const_path unless const_path.nil?
+
+ if !warnings_on_first_load or history.include?(expanded)
+ result = load_file(*load_args)
+ else
+ enable_warnings { result = load_file(*load_args) }
+ end
else
- enable_warnings { result = load_file(*load_args) }
+ log "requiring #{file_name}"
+ result = require file_name
end
- else
- log "requiring #{file_name}"
- result = require file_name
+ rescue Exception
+ loaded.delete expanded
+ raise
+ ensure
+ loading.pop
end
- rescue Exception
- loaded.delete expanded
- raise
- ensure
- loading.pop
- end
- # Record history *after* loading so first load gets warnings.
- history << expanded
- result
+ # Record history *after* loading so first load gets warnings.
+ history << expanded
+ result
+ end
end
# Is the provided constant path defined?