Per-content type indexing settings and debug-time performance

Added type definition template and settings to indexing project
Indexing task check setting per content type while working
WebFormViewEngine provider and cache components moved to dedicated namespace
Subclass of MVC2 wfve created to use a new asp.net 4 api (avoiding FileExists exception improves performance when debugger is attached)

--HG--
branch : dev
This commit is contained in:
Louis DeJardin
2010-06-30 12:38:21 -07:00
parent 01f8617078
commit 2b1dd7d3b0
15 changed files with 133 additions and 46 deletions

View File

@@ -21,7 +21,7 @@
<add name="CaptureTraceMessages" />
</listeners>
</source>
<source name="Orchard.Mvc.ViewEngines.WebFormsViewEngineProvider" switchValue="Warning">
<source name="Orchard.Mvc.ViewEngines.WebFormViewEngineProvider" switchValue="Warning">
<listeners>
<add name="CaptureTraceMessages" />
</listeners>

View File

@@ -1,7 +1,7 @@
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="Default" switchValue="Verbose">
<source name="Default" switchValue="Warning">
<listeners>
<add name="OrchardDebugTextLog" />
<add name="WebPageTrace"/>

View File

@@ -56,6 +56,7 @@
<ItemGroup>
<Content Include="Module.txt" />
<Content Include="Views\Admin\Index.ascx" />
<Content Include="Views\DefinitionTemplates\TypeIndexing.ascx" />
<Content Include="Web.config" />
</ItemGroup>
<ItemGroup>
@@ -77,6 +78,8 @@
<Compile Include="Models\LuceneSearchHit.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\IndexService.cs" />
<Compile Include="Settings\ContentDefinitionEditorEvents.cs" />
<Compile Include="Settings\TypeIndexing.cs" />
<Compile Include="ViewModels\IndexViewModel.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -5,6 +5,7 @@ using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.Data;
using Orchard.Indexing.Models;
using Orchard.Indexing.Settings;
using Orchard.Logging;
using Orchard.Services;
using Orchard.Tasks.Indexing;
@@ -23,7 +24,7 @@ namespace Orchard.Indexing.Services {
private readonly IContentManager _contentManager;
private readonly IIndexSynLock _indexSynLock;
private const string SearchIndexName = "Search";
public IndexingTaskExecutor(
IClock clock,
IRepository<IndexingTaskRecord> repository,
@@ -45,7 +46,7 @@ namespace Orchard.Indexing.Services {
public void UpdateIndex(string indexName) {
var synLock = _indexSynLock.GetSynLock(SearchIndexName);
if ( !System.Threading.Monitor.TryEnter(synLock) ) {
if (!System.Threading.Monitor.TryEnter(synLock)) {
Logger.Information("Index was requested but was already running");
return;
}
@@ -70,10 +71,15 @@ namespace Orchard.Indexing.Services {
// get every existing content item to index it
foreach (var contentItem in _contentManager.Query(VersionOptions.Published).List()) {
try {
var documentIndex = _indexProvider.New(contentItem.Id);
// skip items which are not indexed
var settings = GetTypeIndexingSettings(contentItem);
if (!settings.Included)
continue;
var documentIndex = _indexProvider.New(contentItem.Id);
_contentManager.Index(contentItem, documentIndex);
if(documentIndex.IsDirty) {
if (documentIndex.IsDirty) {
updateIndexDocuments.Add(documentIndex);
}
}
@@ -91,8 +97,10 @@ namespace Orchard.Indexing.Services {
_indexProvider.SetLastIndexUtc(SearchIndexName, _clock.UtcNow);
// retrieve not yet processed tasks
var taskRecords = _repository.Fetch(x => x.CreatedUtc > lastIndexing)
.ToArray();
var taskRecords = lastIndexing == DateTime.MinValue
? _repository.Fetch(x => true).ToArray()
: _repository.Fetch(x => x.CreatedUtc > lastIndexing).ToArray();
// nothing to do ?
if (taskRecords.Length + updateIndexDocuments.Count == 0)
@@ -116,11 +124,15 @@ namespace Orchard.Indexing.Services {
foreach (var taskRecord in taskRecords.Where(t => t.Action == IndexingTaskRecord.Update)) {
var task = new IndexingTask(_contentManager, taskRecord);
// skip items which are not indexed
var settings = GetTypeIndexingSettings(task.ContentItem);
if (!settings.Included)
continue;
try {
var documentIndex = _indexProvider.New(task.ContentItem.Id);
_contentManager.Index(task.ContentItem, documentIndex);
if ( documentIndex.IsDirty ) {
if (documentIndex.IsDirty) {
updateIndexDocuments.Add(documentIndex);
}
@@ -143,5 +155,14 @@ namespace Orchard.Indexing.Services {
System.Threading.Monitor.Exit(synLock);
}
}
static TypeIndexing GetTypeIndexingSettings(ContentItem contentItem) {
if (contentItem == null ||
contentItem.TypeDefinition == null ||
contentItem.TypeDefinition.Settings == null) {
return new TypeIndexing { Included = false };
}
return contentItem.TypeDefinition.Settings.GetModel<TypeIndexing>();
}
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.ContentManagement.MetaData.Builders;
using Orchard.ContentManagement.MetaData.Models;
using Orchard.ContentManagement.ViewModels;
namespace Orchard.Indexing.Settings {
public class ContentDefinitionEditorEvents : ContentDefinitionEditorEventsBase {
public override IEnumerable<TemplateViewModel> TypeEditor(ContentTypeDefinition definition) {
var model = definition.Settings.GetModel<TypeIndexing>();
yield return DefinitionTemplate(model);
}
public override IEnumerable<TemplateViewModel> TypeEditorUpdate(ContentTypeDefinitionBuilder builder, IUpdateModel updateModel) {
var model = new TypeIndexing();
updateModel.TryUpdateModel(model, "TypeIndexing", null, null);
builder
.WithSetting("TypeIndexing.Included", model.Included ? true.ToString() : null);
yield return DefinitionTemplate(model);
}
}
}

View File

@@ -0,0 +1,5 @@
namespace Orchard.Indexing.Settings {
public class TypeIndexing {
public bool Included { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<Orchard.Indexing.Settings.TypeIndexing>" %>
<%@ Import Namespace="Orchard.Mvc.Html" %>
<fieldset>
<%:Html.EditorFor(m=>m.Included) %>
<label for="<%:Html.FieldIdFor(m => m.Included) %>" class="forcheckbox"><%:T("Index this content type for search") %></label>
<%:Html.ValidationMessageFor(m=>m.Included) %>
</fieldset>

View File

@@ -16,6 +16,7 @@ using Orchard.Mvc.Filters;
using Orchard.Mvc.ModelBinders;
using Orchard.Mvc.Routes;
using Orchard.Mvc.ViewEngines;
using Orchard.Mvc.ViewEngines.WebForms;
using Orchard.Settings;
using Orchard.Setup.Commands;
using Orchard.Themes;
@@ -33,7 +34,7 @@ namespace Orchard.Setup {
builder.RegisterModule(new CommandModule());
builder.RegisterType<RoutePublisher>().As<IRoutePublisher>().InstancePerLifetimeScope();
builder.RegisterType<ModelBinderPublisher>().As<IModelBinderPublisher>().InstancePerLifetimeScope();
builder.RegisterType<WebFormsViewEngineProvider>().As<IViewEngineProvider>().InstancePerLifetimeScope();
builder.RegisterType<WebFormViewEngineProvider>().As<IViewEngineProvider>().InstancePerLifetimeScope();
builder.RegisterType<ViewEngineFilter>().As<IFilterProvider>().InstancePerLifetimeScope();
builder.RegisterType<ThemeFilter>().As<IFilterProvider>().InstancePerLifetimeScope();
builder.RegisterType<PageTitleBuilder>().As<IPageTitleBuilder>().InstancePerLifetimeScope();

View File

@@ -41,7 +41,7 @@ namespace Orchard.Environment {
_routePublisher.Publish(_routeProviders.SelectMany(provider => provider.GetRoutes()));
_modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));
AddOrchardLocationsFormats();
//AddOrchardLocationsFormats();
using (var events = _eventsFactory()) {
events.Value.Activated();

View File

@@ -31,7 +31,6 @@ namespace Orchard.Mvc.ViewEngines {
if (skipLayoutViewEngine)
return new ViewEngineResult(Enumerable.Empty<string>());
var bodyView = _viewEngines.FindPartialView(controllerContext, viewName);
ViewEngineResult layoutView = null;
@@ -109,7 +108,6 @@ namespace Orchard.Mvc.ViewEngines {
return new ViewEngineResult(Enumerable.Empty<string>());
}
public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) {
var scope = Scope.From(controllerContext);
if (scope != null && scope.LayoutViewEngine != null) {
@@ -120,10 +118,7 @@ namespace Orchard.Mvc.ViewEngines {
return new ViewEngineResult(Enumerable.Empty<string>());
}
public void ReleaseView(ControllerContext controllerContext, IView view) {
throw new NotImplementedException();
}
}

View File

@@ -63,7 +63,7 @@ namespace Orchard.Mvc.ViewEngines {
var requestViewEngines = new ViewEngineCollection(
themeViewEngines
.Concat(moduleViewEngines)
.Concat(_viewEngines.Where(x => x.GetType().Assembly != typeof(LayoutViewEngine).Assembly))
.Concat(_viewEngines.Where(ViewEngineIsForwarded))
.ToArray());
var layoutViewEngine = new LayoutViewEngine(requestViewEngines);
@@ -72,6 +72,14 @@ namespace Orchard.Mvc.ViewEngines {
viewResultBase.ViewEngineCollection.Insert(0, layoutViewEngine);
}
static bool ViewEngineIsForwarded(IViewEngine x) {
// default view engine, and layout view engine, are not forwarded to
// be used for resolving partials
return
x.GetType().Assembly != typeof(LayoutViewEngine).Assembly &&
x.GetType() != typeof(WebFormViewEngine);
}
public void OnResultExecuted(ResultExecutedContext filterContext) {
}

View File

@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Caching;
using System.Web;
using System.Web.Hosting;
namespace Orchard.Mvc.ViewEngines {
namespace Orchard.Mvc.ViewEngines.WebForms {
public class ThemeViewLocationCache : IViewLocationCache {
private readonly string _requestTheme;

View File

@@ -0,0 +1,25 @@
using System.Web;
using System.Web.Compilation;
using System.Web.Mvc;
namespace Orchard.Mvc.ViewEngines.WebForms {
public class WebFormViewEngineForAspNet4 : WebFormViewEngine {
protected override bool FileExists(ControllerContext controllerContext, string virtualPath) {
try {
return BuildManager.GetObjectFactory(virtualPath, false) != null;
}
catch (HttpException exception) {
// Reproducing base class behavior, however these this code path should
// not be followed for "not found" cases
if (exception is HttpParseException) {
throw;
}
if ((exception.GetHttpCode() != 0x194) || base.FileExists(controllerContext, virtualPath)) {
throw;
}
return false;
}
}
}
}

View File

@@ -2,9 +2,9 @@
using System.Web.Mvc;
using Orchard.Logging;
namespace Orchard.Mvc.ViewEngines {
public class WebFormsViewEngineProvider : IViewEngineProvider {
public WebFormsViewEngineProvider() {
namespace Orchard.Mvc.ViewEngines.WebForms {
public class WebFormViewEngineProvider : IViewEngineProvider {
public WebFormViewEngineProvider() {
Logger = NullLogger.Instance;
}
static string[] DisabledFormats = new[] { "~/Disabled" };
@@ -22,35 +22,35 @@ namespace Orchard.Mvc.ViewEngines {
// Partial Paths -
// {area}/{controller}/
var viewEngine = new WebFormViewEngine {
MasterLocationFormats = DisabledFormats,
ViewLocationFormats = DisabledFormats,
AreaMasterLocationFormats = DisabledFormats,
AreaViewLocationFormats = DisabledFormats,
AreaPartialViewLocationFormats = DisabledFormats,
};
viewEngine.ViewLocationCache = new ThemeViewLocationCache(parameters.VirtualPath);
// for "routed" request views...
// enable /Views/{area}/{controller}/{viewName}
// enable /Views/{partialName}
// enable /Views/"DisplayTemplates/"+{templateName}
// enable /Views/"EditorTemplates/+{templateName}
viewEngine.PartialViewLocationFormats = new[] {
var partialViewLocationFormats = new[] {
parameters.VirtualPath + "/Views/{0}.ascx",
parameters.VirtualPath + "/Views/{0}.aspx",
};
Logger.Debug("PartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", viewEngine.PartialViewLocationFormats));
//Logger.Debug("PartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", partialViewLocationFormats));
// for "routed" request views...
// enable /Views/{area}/{controller}/{viewName}
viewEngine.AreaPartialViewLocationFormats = new[] {
var areaPartialViewLocationFormats = new[] {
parameters.VirtualPath + "/Views/{2}/{1}/{0}.ascx",
parameters.VirtualPath + "/Views/{2}/{1}/{0}.aspx",
};
Logger.Debug("AreaPartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", viewEngine.AreaPartialViewLocationFormats));
//Logger.Debug("AreaPartialViewLocationFormats (theme): \r\n\t-{0}", string.Join("\r\n\t-", areaPartialViewLocationFormats));
var viewEngine = new WebFormViewEngineForAspNet4 {
MasterLocationFormats = DisabledFormats,
ViewLocationFormats = DisabledFormats,
PartialViewLocationFormats = partialViewLocationFormats,
AreaMasterLocationFormats = DisabledFormats,
AreaViewLocationFormats = DisabledFormats,
AreaPartialViewLocationFormats = areaPartialViewLocationFormats,
ViewLocationCache = new ThemeViewLocationCache(parameters.VirtualPath),
};
return viewEngine;
}
@@ -63,7 +63,7 @@ namespace Orchard.Mvc.ViewEngines {
"~/Modules/{2}/Views/{1}/{0}.aspx",
};
Logger.Debug("AreaFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", areaFormats));
//Logger.Debug("AreaFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", areaFormats));
var universalFormats = parameters.VirtualPaths
.SelectMany(x => new[] {
@@ -72,9 +72,9 @@ namespace Orchard.Mvc.ViewEngines {
})
.ToArray();
Logger.Debug("UniversalFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", universalFormats));
//Logger.Debug("UniversalFormats (module): \r\n\t-{0}", string.Join("\r\n\t-", universalFormats));
var viewEngine = new WebFormViewEngine {
var viewEngine = new WebFormViewEngineForAspNet4 {
MasterLocationFormats = DisabledFormats,
ViewLocationFormats = universalFormats,
PartialViewLocationFormats = universalFormats,

View File

@@ -463,6 +463,7 @@
<Compile Include="Environment\DefaultOrchardHost.cs" />
<Compile Include="Mvc\OrchardControllerFactory.cs" />
<Compile Include="Environment\IOrchardHost.cs" />
<Compile Include="Mvc\ViewEngines\WebForms\WebFormViewEngineForAspNet4.cs" />
<Compile Include="OrchardCoreException.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Indexing\IIndexDocument.cs" />
@@ -557,7 +558,7 @@
<Compile Include="Mvc\Routes\UrlPrefix.cs" />
<Compile Include="Mvc\Routes\UrlPrefixAdjustedHttpContext.cs" />
<Compile Include="Mvc\Routes\ShellRoute.cs" />
<Compile Include="Mvc\ViewEngines\ThemeViewLocationCache.cs" />
<Compile Include="Mvc\ViewEngines\WebForms\ThemeViewLocationCache.cs" />
<Compile Include="Mvc\ViewModels\AdaptedViewModel.cs" />
<Compile Include="Mvc\ViewUserControl.cs">
<SubType>ASPXCodeBehind</SubType>
@@ -644,7 +645,7 @@
<Compile Include="Mvc\ViewEngines\LayoutViewEngine.cs" />
<Compile Include="Mvc\ViewEngines\LayoutViewContext.cs" />
<Compile Include="Mvc\ViewEngines\ViewEngineFilter.cs" />
<Compile Include="Mvc\ViewEngines\WebFormsViewEngineProvider.cs" />
<Compile Include="Mvc\ViewEngines\WebForms\WebFormViewEngineProvider.cs" />
<Compile Include="Mvc\ViewModels\BaseViewModel.cs" />
<Compile Include="UI\Admin\AdminThemeSelector.cs" />
<Compile Include="UI\Navigation\INavigationManager.cs" />