Delay recalculating sitemap until absolutely necessary, avoiding redundant recalculations.
This commit is contained in:
parent
a8a555c101
commit
6c241603ac
|
@ -242,6 +242,7 @@ module Middleman::Cli
|
|||
|
||||
# Double-check for compass sprites
|
||||
@app.files.find_new_files((Pathname(@app.source_dir) + @app.images_dir).relative_path_from(@app.root_path))
|
||||
@app.sitemap.ensure_resource_list_updated!
|
||||
|
||||
# Sort paths to be built by the above order. This is primarily so Compass can
|
||||
# find files in the build folder when it needs to generate sprites for the
|
||||
|
|
|
@ -11,7 +11,7 @@ module Middleman
|
|||
/^\.sass-cache\//,
|
||||
/^\.git\//,
|
||||
/^\.gitignore$/,
|
||||
/^\.DS_Store$/,
|
||||
/\.DS_Store/,
|
||||
/^build\//,
|
||||
/^\.rbenv-.*$/,
|
||||
/^Gemfile$/,
|
||||
|
@ -116,17 +116,14 @@ module Middleman
|
|||
path = Pathname(path)
|
||||
return unless path.exist?
|
||||
|
||||
glob = (path + "**/*").to_s
|
||||
glob = (path + "**").to_s
|
||||
subset = @known_paths.select { |p| p.fnmatch(glob) }
|
||||
|
||||
::Middleman::Util.all_files_under(path).each do |filepath|
|
||||
if only_new
|
||||
next if subset.include?(filepath)
|
||||
else
|
||||
subset.delete(filepath)
|
||||
end
|
||||
next if only_new && subset.include?(filepath)
|
||||
|
||||
self.did_change(filepath)
|
||||
subset.delete(filepath)
|
||||
did_change(filepath)
|
||||
end
|
||||
|
||||
subset.each(&method(:did_delete)) unless only_new
|
||||
|
|
|
@ -14,7 +14,6 @@ module Middleman
|
|||
def initialize(sitemap)
|
||||
@sitemap = sitemap
|
||||
@app = @sitemap.app
|
||||
|
||||
@file_paths_on_disk = Set.new
|
||||
|
||||
scoped_self = self
|
||||
|
@ -22,17 +21,18 @@ module Middleman
|
|||
|
||||
# Register file change callback
|
||||
@app.files.changed do |file|
|
||||
scoped_self.touch_file(file, !scoped_self.waiting_for_ready)
|
||||
scoped_self.touch_file(file)
|
||||
end
|
||||
|
||||
# Register file delete callback
|
||||
@app.files.deleted do |file|
|
||||
scoped_self.remove_file(file, !scoped_self.waiting_for_ready)
|
||||
scoped_self.remove_file(file)
|
||||
end
|
||||
|
||||
@app.ready do
|
||||
scoped_self.waiting_for_ready = false
|
||||
scoped_self.sitemap.rebuild_resource_list!(:on_disk_ready)
|
||||
# Make sure the sitemap is ready for the first request
|
||||
sitemap.ensure_resource_list_updated!
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -55,7 +55,13 @@ module Middleman
|
|||
# in case one of the other manipulators
|
||||
# (like asset_hash) cares about the contents of this file,
|
||||
# whether or not it belongs in the sitemap (like a partial)
|
||||
@sitemap.rebuild_resource_list!(:touched_file) if rebuild
|
||||
@sitemap.rebuild_resource_list!(:touched_file)
|
||||
|
||||
unless waiting_for_ready || @app.build?
|
||||
# Force sitemap rebuild so the next request is ready to go.
|
||||
# Skip this during build because the builder will control sitemap refresh.
|
||||
@sitemap.ensure_resource_list_updated!
|
||||
end
|
||||
end
|
||||
|
||||
# Remove a file from the store
|
||||
|
@ -63,7 +69,12 @@ module Middleman
|
|||
# @return [void]
|
||||
def remove_file(file, rebuild=true)
|
||||
if @file_paths_on_disk.delete?(file)
|
||||
@sitemap.rebuild_resource_list!(:removed_file) if rebuild
|
||||
@sitemap.rebuild_resource_list!(:removed_file)
|
||||
unless waiting_for_ready || @app.build?
|
||||
# Force sitemap rebuild so the next request is ready to go.
|
||||
# Skip this during build because the builder will control sitemap refresh.
|
||||
@sitemap.ensure_resource_list_updated!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,41 +23,32 @@ module Middleman
|
|||
@app = app
|
||||
@resources = []
|
||||
@_cached_metadata = {}
|
||||
@_lookup_cache = { :path => {}, :destination_path => {} }
|
||||
@resource_list_manipulators = []
|
||||
@needs_sitemap_rebuild = true
|
||||
reset_lookup_cache!
|
||||
|
||||
# Register classes which can manipulate the main site map list
|
||||
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self), false)
|
||||
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self))
|
||||
|
||||
# Proxies
|
||||
register_resource_list_manipulator(:proxies, @app.proxy_manager, false)
|
||||
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
||||
end
|
||||
|
||||
# Register a klass which can manipulate the main site map list
|
||||
# Register a klass which can manipulate the main site map list. Best to register
|
||||
# these in a before_configuration or after_configuration hook.
|
||||
#
|
||||
# @param [Symbol] name Name of the manipulator for debugging
|
||||
# @param [Class, Module] inst Abstract namespace which can update the resource list
|
||||
# @param [Boolean] immediately_rebuild Whether the resource list should be immediately recalculated
|
||||
# @return [void]
|
||||
def register_resource_list_manipulator(name, inst, immediately_rebuild=true)
|
||||
def register_resource_list_manipulator(name, inst, unused=true)
|
||||
@resource_list_manipulators << [name, inst]
|
||||
rebuild_resource_list!(:registered_new) if immediately_rebuild
|
||||
rebuild_resource_list!(:registered_new)
|
||||
end
|
||||
|
||||
# Rebuild the list of resources from scratch, using registed manipulators
|
||||
# @return [void]
|
||||
def rebuild_resource_list!(reason=nil)
|
||||
@resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
|
||||
newres = inst.manipulate_resource_list(result)
|
||||
|
||||
# Reset lookup cache
|
||||
@_lookup_cache = { :path => {}, :destination_path => {} }
|
||||
newres.each do |resource|
|
||||
@_lookup_cache[:path][resource.path] = resource
|
||||
@_lookup_cache[:destination_path][resource.destination_path] = resource
|
||||
end
|
||||
|
||||
newres
|
||||
end
|
||||
@needs_sitemap_rebuild = true
|
||||
end
|
||||
|
||||
# Find a resource given its original path
|
||||
|
@ -65,7 +56,8 @@ module Middleman
|
|||
# @return [Middleman::Sitemap::Resource]
|
||||
def find_resource_by_path(request_path)
|
||||
request_path = ::Middleman::Util.normalize_path(request_path)
|
||||
@_lookup_cache[:path][request_path]
|
||||
ensure_resource_list_updated!
|
||||
@_lookup_by_path[request_path]
|
||||
end
|
||||
|
||||
# Find a resource given its destination path
|
||||
|
@ -73,13 +65,15 @@ module Middleman
|
|||
# @return [Middleman::Sitemap::Resource]
|
||||
def find_resource_by_destination_path(request_path)
|
||||
request_path = ::Middleman::Util.normalize_path(request_path)
|
||||
@_lookup_cache[:destination_path][request_path]
|
||||
ensure_resource_list_updated!
|
||||
@_lookup_by_destination_path[request_path]
|
||||
end
|
||||
|
||||
# Get the array of all resources
|
||||
# @param [Boolean] include_ignored Whether to include ignored resources
|
||||
# @return [Array<Middleman::Sitemap::Resource>]
|
||||
def resources(include_ignored=false)
|
||||
ensure_resource_list_updated!
|
||||
if include_ignored
|
||||
@resources
|
||||
else
|
||||
|
@ -214,6 +208,36 @@ module Middleman
|
|||
|
||||
path
|
||||
end
|
||||
|
||||
# Actually update the resource list, assuming anything has called
|
||||
# rebuild_resource_list! since the last time it was run. This is
|
||||
# very expensive!
|
||||
def ensure_resource_list_updated!
|
||||
return unless @needs_sitemap_rebuild
|
||||
@needs_sitemap_rebuild = false
|
||||
|
||||
@app.logger.debug "== Rebuilding resource list"
|
||||
|
||||
@resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
|
||||
newres = inst.manipulate_resource_list(result)
|
||||
|
||||
# Reset lookup cache
|
||||
reset_lookup_cache!
|
||||
newres.each do |resource|
|
||||
@_lookup_by_path[resource.path] = resource
|
||||
@_lookup_by_destination_path[resource.destination_path] = resource
|
||||
end
|
||||
|
||||
newres
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def reset_lookup_cache!
|
||||
@_lookup_by_path = {}
|
||||
@_lookup_by_destination_path = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,7 @@ module Middleman
|
|||
:asset_hash,
|
||||
AssetHashManager.new(self, exts, ignore)
|
||||
)
|
||||
|
||||
use Middleware, :exts => exts, :middleman_app => self, :ignore => ignore
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module Middleman
|
|||
|
||||
# Once registered
|
||||
def registered(app)
|
||||
app.ready do
|
||||
app.after_configuration do
|
||||
sitemap.register_resource_list_manipulator(
|
||||
:directory_indexes,
|
||||
DirectoryIndexManager.new(self)
|
||||
|
|
Loading…
Reference in a new issue