Move last write time computation out of loaders

Loaders should only know about dependencies, not about modification
dates. This will help centralizing and abstracting away (for
performance reason) the algorithm used to pick the correct
module to activate (according to last modification dates).

--HG--
branch : 1.x
This commit is contained in:
Renaud Paquay
2011-05-28 20:44:46 -07:00
parent 23afea8a0e
commit ec7e44db4f
8 changed files with 42 additions and 14 deletions
@@ -96,7 +96,7 @@ namespace Orchard.Environment.Extensions {
foreach (var probe in extensionProbes) {
Logger.Debug(" Loader: {0}", probe.Loader.Name);
Logger.Debug(" VirtualPath: {0}", probe.VirtualPath);
Logger.Debug(" DateTimeUtc: {0}", probe.LastWriteTimeUtc);
Logger.Debug(" VirtualPathDependencies: {0}", string.Join(", ", probe.VirtualPathDependencies));
}
}
@@ -175,12 +175,13 @@ namespace Orchard.Environment.Extensions {
var previousDependencies = _dependenciesFolder.LoadDescriptors().ToList();
var virtualPathModficationDates = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase);
var availableExtensionsProbes = availableExtensions.SelectMany(extension => _loaders
.Select(loader => loader.Probe(extension))
.Where(probe => probe != null))
.GroupBy(e => e.Descriptor.Id)
.ToDictionary(g => g.Key, g => g.AsEnumerable()
.OrderByDescending(probe => probe.LastWriteTimeUtc)
.OrderByDescending(probe => GetLatestModificationTimeUtc(virtualPathModficationDates, probe))
.ThenBy(probe => probe.Loader.Order), StringComparer.OrdinalIgnoreCase);
var deletedDependencies = previousDependencies
@@ -214,10 +215,30 @@ namespace Orchard.Environment.Extensions {
DeletedDependencies = deletedDependencies,
AvailableExtensionsProbes = availableExtensionsProbes,
ReferencesByName = referencesByName,
ReferencesByModule = referencesByModule
ReferencesByModule = referencesByModule,
VirtualPathModficationDates = virtualPathModficationDates,
};
}
private DateTime GetLatestModificationTimeUtc(Dictionary<string, DateTime> virtualPathDependencies, ExtensionProbeEntry probe) {
if (!probe.VirtualPathDependencies.Any())
return DateTime.MinValue;
Logger.Information("Retrieving modification dates of dependencies of extension '{0}'", probe.Descriptor.Id);
var result = probe.VirtualPathDependencies.Max(path => {
DateTime dateTime;
if (!virtualPathDependencies.TryGetValue(path, out dateTime)) {
dateTime = _virtualPathProvider.GetFileLastWriteTimeUtc(path);
virtualPathDependencies.Add(path, dateTime);
}
return dateTime;
});
Logger.Information("Done retrieving modification dates of dependencies of extension '{0}'", probe.Descriptor.Id);
return result;
}
IEnumerable<DependencyReferenceDescriptor> ProcessExtensionReferences(ExtensionLoadingContext context, ExtensionProbeEntry activatedExtension) {
if (activatedExtension == null)
return Enumerable.Empty<DependencyReferenceDescriptor>();
@@ -25,6 +25,11 @@ namespace Orchard.Environment.Extensions {
public bool RestartAppDomain { get; set; }
/// <summary>
/// Keep track of modification date of files (VirtualPath => DateTime)
/// </summary>
public IDictionary<string, DateTime> VirtualPathModficationDates { get; set; }
/// <summary>
/// List of extensions (modules) present in the system
/// </summary>
@@ -31,9 +31,9 @@ namespace Orchard.Environment.Extensions.Loaders {
if (descriptor.Location == "~/Core") {
return new ExtensionProbeEntry {
Descriptor = descriptor,
LastWriteTimeUtc = DateTime.MinValue,
Loader = this,
VirtualPath = "~/Core/" + descriptor.Id
VirtualPath = "~/Core/" + descriptor.Id,
VirtualPathDependencies = Enumerable.Empty<string>(),
};
}
return null;
@@ -170,9 +170,9 @@ namespace Orchard.Environment.Extensions.Loaders {
var result = new ExtensionProbeEntry {
Descriptor = descriptor,
LastWriteTimeUtc = GetDependencies(projectPath).Max(f => _virtualPathProvider.GetFileLastWriteTimeUtc(f)),
Loader = this,
VirtualPath = projectPath
VirtualPath = projectPath,
VirtualPathDependencies = GetDependencies(projectPath).ToList(),
};
Logger.Information("Done probing for module '{0}'", descriptor.Id);
@@ -10,7 +10,7 @@ namespace Orchard.Environment.Extensions.Loaders {
public ExtensionDescriptor Descriptor { get; set; }
public IExtensionLoader Loader { get; set; }
public string VirtualPath { get; set; }
public DateTime LastWriteTimeUtc { get; set; }
public IEnumerable<string> VirtualPathDependencies { get; set; }
}
public class ExtensionReferenceProbeEntry {
@@ -192,9 +192,9 @@ namespace Orchard.Environment.Extensions.Loaders {
var result = new ExtensionProbeEntry {
Descriptor = descriptor,
LastWriteTimeUtc = _virtualPathProvider.GetFileLastWriteTimeUtc(assemblyPath),
Loader = this,
VirtualPath = assemblyPath
VirtualPath = assemblyPath,
VirtualPathDependencies = new[] { assemblyPath },
};
Logger.Information("Done probing for module '{0}'", descriptor.Id);
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.Dependencies;
using Orchard.FileSystems.VirtualPath;
@@ -42,9 +43,9 @@ namespace Orchard.Environment.Extensions.Loaders {
return new ExtensionProbeEntry {
Descriptor = descriptor,
LastWriteTimeUtc = DateTime.MinValue,
Loader = this,
VirtualPath = "~/Theme/" + descriptor.Id
VirtualPath = "~/Theme/" + descriptor.Id,
VirtualPathDependencies = Enumerable.Empty<string>(),
};
}
return null;
@@ -1,4 +1,5 @@
using System.IO;
using System.Linq;
using Orchard.Environment.Extensions.Models;
using Orchard.FileSystems.Dependencies;
using Orchard.FileSystems.VirtualPath;
@@ -57,9 +58,9 @@ namespace Orchard.Environment.Extensions.Loaders {
return new ExtensionProbeEntry {
Descriptor = descriptor,
LastWriteTimeUtc = _virtualPathProvider.GetFileLastWriteTimeUtc(assemblyPath),
Loader = this,
VirtualPath = assemblyPath
VirtualPath = assemblyPath,
VirtualPathDependencies = new[] { assemblyPath },
};
}