Make Sitemap::Store more thread-safe.
This commit is contained in:
parent
0d806277f9
commit
c40102cf53
|
@ -1,5 +1,6 @@
|
||||||
# Used for merging results of metadata callbacks
|
# Used for merging results of metadata callbacks
|
||||||
require "active_support/core_ext/hash/deep_merge"
|
require "active_support/core_ext/hash/deep_merge"
|
||||||
|
require 'monitor'
|
||||||
|
|
||||||
module Middleman
|
module Middleman
|
||||||
|
|
||||||
|
@ -25,6 +26,8 @@ module Middleman
|
||||||
@_cached_metadata = {}
|
@_cached_metadata = {}
|
||||||
@resource_list_manipulators = []
|
@resource_list_manipulators = []
|
||||||
@needs_sitemap_rebuild = true
|
@needs_sitemap_rebuild = true
|
||||||
|
@lock = Monitor.new
|
||||||
|
|
||||||
reset_lookup_cache!
|
reset_lookup_cache!
|
||||||
|
|
||||||
# Register classes which can manipulate the main site map list
|
# Register classes which can manipulate the main site map list
|
||||||
|
@ -48,36 +51,44 @@ module Middleman
|
||||||
# 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)
|
||||||
@needs_sitemap_rebuild = true
|
@lock.synchronize do
|
||||||
|
@needs_sitemap_rebuild = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find a resource given its original path
|
# Find a resource given its original path
|
||||||
# @param [String] request_path The original path of a resource.
|
# @param [String] request_path The original path of a resource.
|
||||||
# @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)
|
@lock.synchronize do
|
||||||
ensure_resource_list_updated!
|
request_path = ::Middleman::Util.normalize_path(request_path)
|
||||||
@_lookup_by_path[request_path]
|
ensure_resource_list_updated!
|
||||||
|
@_lookup_by_path[request_path]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Find a resource given its destination path
|
# Find a resource given its destination path
|
||||||
# @param [String] request_path The destination (output) path of a resource.
|
# @param [String] request_path The destination (output) path of a resource.
|
||||||
# @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)
|
@lock.synchronize do
|
||||||
ensure_resource_list_updated!
|
request_path = ::Middleman::Util.normalize_path(request_path)
|
||||||
@_lookup_by_destination_path[request_path]
|
ensure_resource_list_updated!
|
||||||
|
@_lookup_by_destination_path[request_path]
|
||||||
|
end
|
||||||
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!
|
@lock.synchronize do
|
||||||
if include_ignored
|
ensure_resource_list_updated!
|
||||||
@resources
|
if include_ignored
|
||||||
else
|
@resources
|
||||||
@resources.reject(&:ignored?)
|
else
|
||||||
|
@resources.reject(&:ignored?)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -201,30 +212,34 @@ module Middleman
|
||||||
# rebuild_resource_list! since the last time it was run. This is
|
# rebuild_resource_list! since the last time it was run. This is
|
||||||
# very expensive!
|
# very expensive!
|
||||||
def ensure_resource_list_updated!
|
def ensure_resource_list_updated!
|
||||||
return unless @needs_sitemap_rebuild
|
@lock.synchronize do
|
||||||
@needs_sitemap_rebuild = false
|
return unless @needs_sitemap_rebuild
|
||||||
|
@needs_sitemap_rebuild = false
|
||||||
|
|
||||||
@app.logger.debug "== Rebuilding resource list"
|
@app.logger.debug "== Rebuilding resource list"
|
||||||
|
|
||||||
@resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
|
@resources = @resource_list_manipulators.inject([]) do |result, (_, inst)|
|
||||||
newres = inst.manipulate_resource_list(result)
|
newres = inst.manipulate_resource_list(result)
|
||||||
|
|
||||||
# Reset lookup cache
|
# Reset lookup cache
|
||||||
reset_lookup_cache!
|
reset_lookup_cache!
|
||||||
newres.each do |resource|
|
newres.each do |resource|
|
||||||
@_lookup_by_path[resource.path] = resource
|
@_lookup_by_path[resource.path] = resource
|
||||||
@_lookup_by_destination_path[resource.destination_path] = resource
|
@_lookup_by_destination_path[resource.destination_path] = resource
|
||||||
|
end
|
||||||
|
|
||||||
|
newres
|
||||||
end
|
end
|
||||||
|
|
||||||
newres
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def reset_lookup_cache!
|
def reset_lookup_cache!
|
||||||
@_lookup_by_path = {}
|
@lock.synchronize {
|
||||||
@_lookup_by_destination_path = {}
|
@_lookup_by_path = {}
|
||||||
|
@_lookup_by_destination_path = {}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue