Class: Bootsnap::LoadPathCache::Cache
- Inherits:
-
Object
- Object
- Bootsnap::LoadPathCache::Cache
- Defined in:
- lib/bootsnap/load_path_cache/cache.rb
Constant Summary collapse
- AGE_THRESHOLD =
seconds
30
- TRUFFLERUBY_LIB_DIR_PREFIX =
if RUBY_ENGINE == "truffleruby" "#{File.join(RbConfig::CONFIG['libdir'], 'truffle')}#{File::SEPARATOR}" end
- BUILTIN_FEATURES =
{ ‘enumerator’ => nil, ‘enumerator.so’ => nil, … }
$LOADED_FEATURES.each_with_object({}) do |feat, features| if TRUFFLERUBY_LIB_DIR_PREFIX && feat.start_with?(TRUFFLERUBY_LIB_DIR_PREFIX) feat = feat.byteslice(TRUFFLERUBY_LIB_DIR_PREFIX.bytesize..-1) end # Builtin features are of the form 'enumerator.so'. # All others include paths. next unless feat.size < 20 && !feat.include?("/") base = File.basename(feat, ".*") # enumerator.so -> enumerator ext = File.extname(feat) # .so features[feat] = nil # enumerator.so features[base] = nil # enumerator next unless [DOT_SO, *DL_EXTENSIONS].include?(ext) DL_EXTENSIONS.each do |dl_ext| features["#{base}#{dl_ext}"] = nil # enumerator.bundle end end.freeze
Instance Method Summary collapse
-
#find(feature) ⇒ Object
Try to resolve this feature to an absolute path without traversing the loadpath.
-
#initialize(store, path_obj, development_mode: false) ⇒ Cache
constructor
A new instance of Cache.
-
#load_dir(dir) ⇒ Object
What is the path item that contains the dir as child? e.g.
- #push_paths(sender, *paths) ⇒ Object
- #reinitialize(path_obj = @path_obj) ⇒ Object
- #unshift_paths(sender, *paths) ⇒ Object
Constructor Details
#initialize(store, path_obj, development_mode: false) ⇒ Cache
Returns a new instance of Cache.
10 11 12 13 14 15 16 17 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 10 def initialize(store, path_obj, development_mode: false) @development_mode = development_mode @store = store @mutex = Mutex.new @path_obj = path_obj.map! { |f| PathScanner.os_path(File.exist?(f) ? File.realpath(f) : f.dup) } @has_relative_paths = nil reinitialize end |
Instance Method Details
#find(feature) ⇒ Object
Try to resolve this feature to an absolute path without traversing the loadpath.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 56 def find(feature) reinitialize if (@has_relative_paths && dir_changed?) || stale? feature = feature.to_s.freeze return feature if Bootsnap.absolute_path?(feature) if feature.start_with?("./", "../") return (feature) end @mutex.synchronize do x = search_index(feature) return x if x # Ruby has some built-in features that require lies about. # For example, 'enumerator' is built in. If you require it, ruby # returns false as if it were already loaded; however, there is no # file to find on disk. We've pre-built a list of these, and we # return false if any of them is loaded. return false if BUILTIN_FEATURES.key?(feature) # The feature wasn't found on our preliminary search through the index. # We resolve this differently depending on what the extension was. case File.extname(feature) # If the extension was one of the ones we explicitly cache (.rb and the # native dynamic extension, e.g. .bundle or .so), we know it was a # failure and there's nothing more we can do to find the file. # no extension, .rb, (.bundle or .so) when "", *CACHED_EXTENSIONS nil # Ruby allows specifying native extensions as '.so' even when DLEXT # is '.bundle'. This is where we handle that case. when DOT_SO x = search_index(feature[0..-4] + DLEXT) return x if x if DLEXT2 x = search_index(feature[0..-4] + DLEXT2) return x if x end else # other, unknown extension. For example, `.rake`. Since we haven't # cached these, we legitimately need to run the load path search. return FALLBACK_SCAN end end # In development mode, we don't want to confidently return failures for # cases where the file doesn't appear to be on the load path. We should # be able to detect newly-created files without rebooting the # application. return FALLBACK_SCAN if @development_mode end |
#load_dir(dir) ⇒ Object
What is the path item that contains the dir as child? e.g. given “/a/b/c/d” exists, and the path is [“/a/b”], load_dir(“c/d”) is “/a/b”.
22 23 24 25 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 22 def load_dir(dir) reinitialize if stale? @mutex.synchronize { @dirs[dir] } end |
#push_paths(sender, *paths) ⇒ Object
116 117 118 119 120 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 116 def push_paths(sender, *paths) return unless sender == @path_obj @mutex.synchronize { push_paths_locked(*paths) } end |
#reinitialize(path_obj = @path_obj) ⇒ Object
122 123 124 125 126 127 128 129 130 131 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 122 def reinitialize(path_obj = @path_obj) @mutex.synchronize do @path_obj = path_obj ChangeObserver.register(@path_obj, self) @index = {} @dirs = {} @generated_at = now push_paths_locked(*@path_obj) end end |
#unshift_paths(sender, *paths) ⇒ Object
110 111 112 113 114 |
# File 'lib/bootsnap/load_path_cache/cache.rb', line 110 def unshift_paths(sender, *paths) return unless sender == @path_obj @mutex.synchronize { unshift_paths_locked(*paths) } end |