Skip to content

Instantly share code, notes, and snippets.

@limhoff-r7
Created September 20, 2013 19:25
Show Gist options
  • Save limhoff-r7/6642574 to your computer and use it in GitHub Desktop.
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.
# `*::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