Created
September 20, 2013 19:25
-
-
Save limhoff-r7/6642574 to your computer and use it in GitHub Desktop.
Finding `Mdm::Module::Class` by INTERSECTING `Mdm::Module::Ancestor#descendants`, which are `Mdm::Module::Classes`, to determine if a new `Mdm::Module::Class` should be created for the combination of one or two `Mdm::Module::Ancestor`. Uses WeakRef to allow garbage collection of `Mdm::Module::Class` after use.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# `*::Module::Class` holding metadata for this class. | |
# | |
# @return [Mdm::Module::Class] | |
def module_class | |
begin | |
strong_reference = nil | |
if @module_class | |
strong_reference = @module_class.__getobj__ | |
else | |
ActiveRecord::Base.connection_pool.with_connection do | |
ActiveRecord::Base.transaction do | |
module_class_sets = module_ancestors.map(&:descendants) | |
module_class_intersection = module_class_sets.inject { |intersection, module_class_set| | |
intersection.intersect module_class_set | |
} | |
module_class_intersection_sql = module_class_intersection.to_sql | |
strong_reference = Mdm::Module::Class.find_by_sql(module_class_intersection_sql).first | |
unless strong_reference | |
strong_reference = Mdm::Module::Class.new(ancestors: ancestors) | |
end | |
end | |
end | |
# memoize as a weak reference so that garbage collector can save memory and thousands of Mdm::Module::Classes | |
# don't have to remain in memory. | |
@module_class = WeakRef.new(strong_reference) | |
end | |
rescue WeakRef::RefError | |
# try again by rebuilding weakref for @module_class | |
@module_class = nil | |
retry | |
end | |
# Return a strong reference so consuming code doesn't have to handle the weakref being garbage collected. | |
strong_reference | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment