PERF: Improve performance of DefaultVirtualPathMonitor

Decrease constant cost of implementation:

* Don't check for file/directory existence. It is much more
  expensive to systematically check for file existence through the
  VPP than catching the occasional exception.

* Don't eagerly create ASP.NET cache entries when there are
  already existing entries. This is so if there are multiple calls
  for the same virtual path, we don't end up calling an expensive
  API when there is no need.

--HG--
branch : 1.x
extra : transplant_source : %C8%C3t%5C%B3%DA%C4%98%E8%13%23%D1B%91%AF2%B7%01%E7%CE
This commit is contained in:
Renaud Paquay
2011-05-04 17:48:37 -07:00
parent 8e7550cda9
commit 0b4bf6276d

View File

@@ -8,6 +8,7 @@ using Orchard.Logging;
using Orchard.Services;
namespace Orchard.FileSystems.VirtualPath {
public class DefaultVirtualPathMonitor : IVirtualPathMonitor {
private readonly Thunk _thunk;
private readonly string _prefix = Guid.NewGuid().ToString("n");
@@ -23,26 +24,18 @@ namespace Orchard.FileSystems.VirtualPath {
public ILogger Logger { get; set; }
public IVolatileToken WhenPathChanges(string virtualPath) {
var token = BindToken(virtualPath);
try {
var token = BindToken(virtualPath);
if (!HostingEnvironment.VirtualPathProvider.DirectoryExists(virtualPath)
&& !HostingEnvironment.VirtualPathProvider.FileExists(virtualPath)) {
// if trying to monitor a directory or file inside a directory which doesn't exist
// monitor first existing parent directory
return new Token(virtualPath);
}
BindSignal(virtualPath);
return token;
}
catch (HttpException e) {
// This exception happens if trying to monitor a directory or file
// inside a directory which doesn't exist
Logger.Warning(e, "Error monitor file changes on virtual path '{0}'", virtualPath);
// Fix this to monitor first existing parent directory.
return new Token(virtualPath);
Logger.Warning(e, "Error monitoring file changes on virtual path '{0}'", virtualPath);
//TODO: Return a token monitoring first existing parent directory.
}
return token;
}
private Token BindToken(string virtualPath) {
@@ -81,13 +74,20 @@ namespace Orchard.FileSystems.VirtualPath {
}
private void BindSignal(string virtualPath, CacheItemRemovedCallback callback) {
string key = _prefix + virtualPath;
//PERF: Don't add in the cache if already present. Creating a "CacheDependency"
// object (below) is actually quite expensive.
if (HostingEnvironment.Cache.Get(key) != null)
return;
var cacheDependency = HostingEnvironment.VirtualPathProvider.GetCacheDependency(
virtualPath,
new[] { virtualPath },
_clock.UtcNow);
HostingEnvironment.Cache.Add(
_prefix + virtualPath,
key,
virtualPath,
cacheDependency,
Cache.NoAbsoluteExpiration,