Merge pull request #603 from bhollis/sitemap_speed
Delay recalculating sitemap until absolutely necessary
This commit is contained in:
commit
56e2a747b7
|
@ -242,6 +242,7 @@ module Middleman::Cli
|
||||||
|
|
||||||
# Double-check for compass sprites
|
# Double-check for compass sprites
|
||||||
@app.files.find_new_files((Pathname(@app.source_dir) + @app.images_dir).relative_path_from(@app.root_path))
|
@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
|
# 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
|
# find files in the build folder when it needs to generate sprites for the
|
||||||
|
|
|
@ -11,7 +11,7 @@ module Middleman
|
||||||
/^\.sass-cache\//,
|
/^\.sass-cache\//,
|
||||||
/^\.git\//,
|
/^\.git\//,
|
||||||
/^\.gitignore$/,
|
/^\.gitignore$/,
|
||||||
/^\.DS_Store$/,
|
/\.DS_Store/,
|
||||||
/^build\//,
|
/^build\//,
|
||||||
/^\.rbenv-.*$/,
|
/^\.rbenv-.*$/,
|
||||||
/^Gemfile$/,
|
/^Gemfile$/,
|
||||||
|
@ -116,17 +116,14 @@ module Middleman
|
||||||
path = Pathname(path)
|
path = Pathname(path)
|
||||||
return unless path.exist?
|
return unless path.exist?
|
||||||
|
|
||||||
glob = (path + "**/*").to_s
|
glob = (path + "**").to_s
|
||||||
subset = @known_paths.select { |p| p.fnmatch(glob) }
|
subset = @known_paths.select { |p| p.fnmatch(glob) }
|
||||||
|
|
||||||
::Middleman::Util.all_files_under(path).each do |filepath|
|
::Middleman::Util.all_files_under(path).each do |filepath|
|
||||||
if only_new
|
next if only_new && subset.include?(filepath)
|
||||||
next if subset.include?(filepath)
|
|
||||||
else
|
|
||||||
subset.delete(filepath)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.did_change(filepath)
|
subset.delete(filepath)
|
||||||
|
did_change(filepath)
|
||||||
end
|
end
|
||||||
|
|
||||||
subset.each(&method(:did_delete)) unless only_new
|
subset.each(&method(:did_delete)) unless only_new
|
||||||
|
|
|
@ -14,7 +14,6 @@ module Middleman
|
||||||
def initialize(sitemap)
|
def initialize(sitemap)
|
||||||
@sitemap = sitemap
|
@sitemap = sitemap
|
||||||
@app = @sitemap.app
|
@app = @sitemap.app
|
||||||
|
|
||||||
@file_paths_on_disk = Set.new
|
@file_paths_on_disk = Set.new
|
||||||
|
|
||||||
scoped_self = self
|
scoped_self = self
|
||||||
|
@ -22,17 +21,18 @@ module Middleman
|
||||||
|
|
||||||
# Register file change callback
|
# Register file change callback
|
||||||
@app.files.changed do |file|
|
@app.files.changed do |file|
|
||||||
scoped_self.touch_file(file, !scoped_self.waiting_for_ready)
|
scoped_self.touch_file(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Register file delete callback
|
# Register file delete callback
|
||||||
@app.files.deleted do |file|
|
@app.files.deleted do |file|
|
||||||
scoped_self.remove_file(file, !scoped_self.waiting_for_ready)
|
scoped_self.remove_file(file)
|
||||||
end
|
end
|
||||||
|
|
||||||
@app.ready do
|
@app.ready do
|
||||||
scoped_self.waiting_for_ready = false
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -55,7 +55,13 @@ module Middleman
|
||||||
# in case one of the other manipulators
|
# in case one of the other manipulators
|
||||||
# (like asset_hash) cares about the contents of this file,
|
# (like asset_hash) cares about the contents of this file,
|
||||||
# whether or not it belongs in the sitemap (like a partial)
|
# 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
|
end
|
||||||
|
|
||||||
# Remove a file from the store
|
# Remove a file from the store
|
||||||
|
@ -63,7 +69,12 @@ module Middleman
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def remove_file(file, rebuild=true)
|
def remove_file(file, rebuild=true)
|
||||||
if @file_paths_on_disk.delete?(file)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,41 +23,32 @@ module Middleman
|
||||||
@app = app
|
@app = app
|
||||||
@resources = []
|
@resources = []
|
||||||
@_cached_metadata = {}
|
@_cached_metadata = {}
|
||||||
@_lookup_cache = { :path => {}, :destination_path => {} }
|
|
||||||
@resource_list_manipulators = []
|
@resource_list_manipulators = []
|
||||||
|
@needs_sitemap_rebuild = true
|
||||||
|
reset_lookup_cache!
|
||||||
|
|
||||||
# Register classes which can manipulate the main site map list
|
# 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
|
# Proxies
|
||||||
register_resource_list_manipulator(:proxies, @app.proxy_manager, false)
|
register_resource_list_manipulator(:proxies, @app.proxy_manager)
|
||||||
end
|
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 [Symbol] name Name of the manipulator for debugging
|
||||||
# @param [Class, Module] inst Abstract namespace which can update the resource list
|
# @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]
|
# @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]
|
@resource_list_manipulators << [name, inst]
|
||||||
rebuild_resource_list!(:registered_new) if immediately_rebuild
|
rebuild_resource_list!(:registered_new)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Rebuild the list of resources from scratch, using registed manipulators
|
# Rebuild the list of resources from scratch, using registed manipulators
|
||||||
# @return [void]
|
# @return [void]
|
||||||
def rebuild_resource_list!(reason=nil)
|
def rebuild_resource_list!(reason=nil)
|
||||||
@resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
|
@needs_sitemap_rebuild = true
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find a resource given its original path
|
# Find a resource given its original path
|
||||||
|
@ -65,7 +56,8 @@ module Middleman
|
||||||
# @return [Middleman::Sitemap::Resource]
|
# @return [Middleman::Sitemap::Resource]
|
||||||
def find_resource_by_path(request_path)
|
def find_resource_by_path(request_path)
|
||||||
request_path = ::Middleman::Util.normalize_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
|
end
|
||||||
|
|
||||||
# Find a resource given its destination path
|
# Find a resource given its destination path
|
||||||
|
@ -73,13 +65,15 @@ module Middleman
|
||||||
# @return [Middleman::Sitemap::Resource]
|
# @return [Middleman::Sitemap::Resource]
|
||||||
def find_resource_by_destination_path(request_path)
|
def find_resource_by_destination_path(request_path)
|
||||||
request_path = ::Middleman::Util.normalize_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
|
end
|
||||||
|
|
||||||
# Get the array of all resources
|
# Get the array of all resources
|
||||||
# @param [Boolean] include_ignored Whether to include ignored resources
|
# @param [Boolean] include_ignored Whether to include ignored resources
|
||||||
# @return [Array<Middleman::Sitemap::Resource>]
|
# @return [Array<Middleman::Sitemap::Resource>]
|
||||||
def resources(include_ignored=false)
|
def resources(include_ignored=false)
|
||||||
|
ensure_resource_list_updated!
|
||||||
if include_ignored
|
if include_ignored
|
||||||
@resources
|
@resources
|
||||||
else
|
else
|
||||||
|
@ -214,6 +208,36 @@ module Middleman
|
||||||
|
|
||||||
path
|
path
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Middleman
|
||||||
:asset_hash,
|
:asset_hash,
|
||||||
AssetHashManager.new(self, exts, ignore)
|
AssetHashManager.new(self, exts, ignore)
|
||||||
)
|
)
|
||||||
|
|
||||||
use Middleware, :exts => exts, :middleman_app => self, :ignore => ignore
|
use Middleware, :exts => exts, :middleman_app => self, :ignore => ignore
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module Middleman
|
||||||
|
|
||||||
# Once registered
|
# Once registered
|
||||||
def registered(app)
|
def registered(app)
|
||||||
app.ready do
|
app.after_configuration do
|
||||||
sitemap.register_resource_list_manipulator(
|
sitemap.register_resource_list_manipulator(
|
||||||
:directory_indexes,
|
:directory_indexes,
|
||||||
DirectoryIndexManager.new(self)
|
DirectoryIndexManager.new(self)
|
||||||
|
|
Loading…
Reference in a new issue