mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix dev env memory leaks by using AS::DescendantsTracker rather than keeping track of subclasses manually.
There's also no need to keep track of all ObserverArray instances in a hash, as this is likely to leak memory, too.
This commit is contained in:
parent
05d4653cef
commit
9a385394ac
2 changed files with 12 additions and 36 deletions
|
@ -4,15 +4,6 @@ module ActiveModel
|
|||
# Stores the enabled/disabled state of individual observers for
|
||||
# a particular model classes.
|
||||
class ObserverArray < Array
|
||||
INSTANCES = Hash.new do |hash, model_class|
|
||||
hash[model_class] = new(model_class)
|
||||
end
|
||||
|
||||
def self.for(model_class)
|
||||
return nil unless model_class < ActiveModel::Observing
|
||||
INSTANCES[model_class]
|
||||
end
|
||||
|
||||
# returns false if:
|
||||
# - the ObserverArray for the given model's class has the given observer
|
||||
# in its disabled_observers set.
|
||||
|
@ -22,7 +13,8 @@ module ActiveModel
|
|||
observer_class = observer.class
|
||||
|
||||
loop do
|
||||
break unless array = self.for(klass)
|
||||
break unless klass.respond_to?(:observers)
|
||||
array = klass.observers
|
||||
return false if array.disabled_observers.include?(observer_class)
|
||||
klass = klass.superclass
|
||||
end
|
||||
|
@ -90,8 +82,8 @@ module ActiveModel
|
|||
end
|
||||
|
||||
def each_subclass_array
|
||||
model_class.subclasses.each do |subclass|
|
||||
yield self.class.for(subclass)
|
||||
model_class.descendants.each do |subclass|
|
||||
yield subclass.observers
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -102,7 +94,7 @@ module ActiveModel
|
|||
yield
|
||||
end
|
||||
else
|
||||
observers = ActiveModel::Observer.all_observers if observers == [:all]
|
||||
observers = ActiveModel::Observer.descendants if observers == [:all]
|
||||
observers.each do |obs|
|
||||
klass = observer_class_for(obs)
|
||||
|
||||
|
|
|
@ -5,11 +5,16 @@ require 'active_support/core_ext/module/aliasing'
|
|||
require 'active_support/core_ext/module/remove_method'
|
||||
require 'active_support/core_ext/string/inflections'
|
||||
require 'active_support/core_ext/enumerable'
|
||||
require 'active_support/descendants_tracker'
|
||||
|
||||
module ActiveModel
|
||||
module Observing
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extend ActiveSupport::DescendantsTracker
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# == Active Model Observers Activation
|
||||
#
|
||||
|
@ -37,7 +42,7 @@ module ActiveModel
|
|||
|
||||
# Gets the current observers.
|
||||
def observers
|
||||
@observers ||= ObserverArray.for(self)
|
||||
@observers ||= ObserverArray.new(self)
|
||||
end
|
||||
|
||||
# Gets the current observer instances.
|
||||
|
@ -70,10 +75,6 @@ module ActiveModel
|
|||
observer_instances.size
|
||||
end
|
||||
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
protected
|
||||
def instantiate_observer(observer) #:nodoc:
|
||||
# string/symbol
|
||||
|
@ -93,7 +94,6 @@ module ActiveModel
|
|||
# Notify observers when the observed class is subclassed.
|
||||
def inherited(subclass)
|
||||
super
|
||||
subclasses << subclass
|
||||
notify_observers :observed_class_inherited, subclass
|
||||
end
|
||||
end
|
||||
|
@ -176,6 +176,7 @@ module ActiveModel
|
|||
#
|
||||
class Observer
|
||||
include Singleton
|
||||
extend ActiveSupport::DescendantsTracker
|
||||
|
||||
class << self
|
||||
# Attaches the observer to the supplied model classes.
|
||||
|
@ -208,23 +209,6 @@ module ActiveModel
|
|||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def subclasses
|
||||
@subclasses ||= []
|
||||
end
|
||||
|
||||
# List of all observer subclasses, sub-subclasses, etc.
|
||||
# Necessary so we can disable or enable all observers.
|
||||
def all_observers
|
||||
subclasses.each_with_object(subclasses.dup) do |subclass, array|
|
||||
array.concat(subclass.all_observers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.inherited(subclass)
|
||||
subclasses << subclass
|
||||
super
|
||||
end
|
||||
|
||||
# Start observing the declared classes and their subclasses.
|
||||
|
|
Loading…
Reference in a new issue