Created
September 20, 2013 21:30
-
-
Save limhoff-r7/6644221 to your computer and use it in GitHub Desktop.
Use WeakRef to allow ActiveRecords to be collected, but allow the ActiveRecord to be recreated when needed. Allows a module, class, or instance to keep track of its own metadata without constantly having the metadata in memory and allowing the metadata to be reused without needing pass it through all the cache construction.
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
resurrecting_attr_accessor :module_ancestor do | |
ActiveRecord::Base.connection_pool.with_connection do | |
Mdm::Module::Ancestor.where(real_path_sha1_hex_digest: real_path_sha1_hex_digest).first | |
end | |
end |
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 Metasploit::Framework::ResurrectingAttribute | |
def resurrecting_attr_accessor(attribute_name, &block) | |
instance_variable_name = "@#{attribute_name}".to_sym | |
getter_name = attribute_name | |
setter_name = "#{attribute_name}=" | |
define_method(getter_name) do | |
begin | |
strong_reference = nil | |
weak_reference = instance_variable_get instance_variable_name | |
if weak_reference | |
strong_reference = weak_reference.__getobj__ | |
else | |
strong_reference = instance_exec(&block) | |
send(setter_name, strong_reference) | |
end | |
rescue WeakRef::RefError | |
# try again by rebuild because __getobj__ failed on the weak_reference because the referenced object was garbage | |
# collected. | |
instance_variable_set instance_variable_name, nil | |
retry | |
end | |
# Return strong reference so consuming code doesn't have to handle the weak_reference being garbase collected. | |
strong_reference | |
end | |
define_method(setter_name) do |strong_reference| | |
weak_reference = WeakRef.new(strong_reference) | |
instance_variable_set instance_variable_name, weak_reference | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment