diff --git a/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs b/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs index 37d65bd50b..457d7edbe6 100644 --- a/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs +++ b/src/Umbraco.Web/PropertyEditors/PropertyEditorsComponent.cs @@ -13,16 +13,13 @@ namespace Umbraco.Web.PropertyEditors { public void Initialize(IRuntimeState runtime, PropertyEditorCollection propertyEditors, IExamineIndexCollectionAccessor indexCollection) { - if (runtime.Level != RuntimeLevel.Run) return; - var fileUpload = propertyEditors.OfType().FirstOrDefault(); if (fileUpload != null) Initialize(fileUpload); var imageCropper = propertyEditors.OfType().FirstOrDefault(); if (imageCropper != null) Initialize(imageCropper); - var grid = propertyEditors.OfType().FirstOrDefault(); - if (grid != null) Initialize(grid, indexCollection); + // grid/examine moved to ExamineComponent } // as long as these methods are private+static they won't be executed by the boot loader @@ -62,13 +59,5 @@ namespace Umbraco.Web.PropertyEditors MemberService.Deleted += (sender, args) => args.MediaFilesToDelete.AddRange(imageCropper.ServiceDeleted(args.DeletedEntities.Cast())); } - - private static void Initialize(GridPropertyEditor grid, IExamineIndexCollectionAccessor indexCollection) - { - var indexes = indexCollection.Indexes; - if (indexes == null) return; - foreach (var i in indexes.Values.OfType()) - i.DocumentWriting += grid.DocumentWriting; - } } } diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index 5348469f05..0a8930ebd0 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; -using System.Xml; +using System.Threading; using System.Xml.Linq; using Examine; using Examine.LuceneEngine; @@ -13,23 +13,56 @@ using Umbraco.Core.Cache; using Umbraco.Core.Components; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; using Umbraco.Core.Services.Changes; using Umbraco.Core.Sync; using Umbraco.Web.Cache; +using Umbraco.Web.PropertyEditors; using UmbracoExamine; namespace Umbraco.Web.Search { /// - /// Used to wire up events for Examine + /// Configures and installs Examine. /// [RuntimeLevel(MinLevel = RuntimeLevel.Run)] public sealed class ExamineComponent : UmbracoComponentBase, IUmbracoCoreComponent { - public void Initialize(ILogger logger) + public void Initialize(IRuntimeState runtime, PropertyEditorCollection propertyEditors, IExamineIndexCollectionAccessor indexCollection, ILogger logger) { - logger.Info("Initializing Examine and binding to business logic events"); + logger.Info("Starting initialize async background thread."); + + // make it async in order not to slow down the boot + var bg = new Thread(() => + { + try + { + // from WebRuntimeComponent + // rebuilds any empty indexes + RebuildIndexes(true); + } + catch (Exception e) + { + logger.Error("Failed to rebuild empty indexes.", e); + } + + try + { + // from PropertyEditorsComponent + var grid = propertyEditors.OfType().FirstOrDefault(); + if (grid != null) BindGridToExamine(grid, indexCollection); + } + catch (Exception e) + { + logger.Error("Failed to bind grid property editor.", e); + } + }); + bg.Start(); + + // the rest is the original Examine event handler + + logger.Info("Initialize and bind to business logic events."); //TODO: For now we'll make this true, it means that indexes will be near real time // we'll see about what implications this may have - should be great in most scenarios @@ -38,7 +71,7 @@ namespace Umbraco.Web.Search var registeredProviders = ExamineManager.Instance.IndexProviderCollection .OfType().Count(x => x.EnableDefaultEventHandler); - logger.Info("Adding examine event handlers for index providers: {0}", () => registeredProviders); + logger.Info($"Adding examine event handlers for {registeredProviders} index providers."); // don't bind event handlers if we're not suppose to listen if (registeredProviders == 0) @@ -62,7 +95,25 @@ namespace Umbraco.Web.Search } } - static void MemberCacheRefresherUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs args) + private static void RebuildIndexes(bool onlyEmptyIndexes) + { + var indexers = (IEnumerable>)ExamineManager.Instance.IndexProviders; + if (onlyEmptyIndexes) + indexers = indexers.Where(x => x.Value.IsIndexNew()); + foreach (var indexer in indexers) + indexer.Value.RebuildIndex(); + } + + + private static void BindGridToExamine(GridPropertyEditor grid, IExamineIndexCollectionAccessor indexCollection) + { + var indexes = indexCollection.Indexes; + if (indexes == null) return; + foreach (var i in indexes.Values.OfType()) + i.DocumentWriting += grid.DocumentWriting; + } + + static void MemberCacheRefresherUpdated(MemberCacheRefresher sender, CacheRefresherEventArgs args) { switch (args.MessageType) { diff --git a/src/Umbraco.Web/WebRuntimeComponent.cs b/src/Umbraco.Web/WebRuntimeComponent.cs index 92d1697eb7..c95b848761 100644 --- a/src/Umbraco.Web/WebRuntimeComponent.cs +++ b/src/Umbraco.Web/WebRuntimeComponent.cs @@ -10,12 +10,10 @@ using System.Web.Http.Dispatcher; using System.Web.Mvc; using System.Web.Routing; using ClientDependency.Core.Config; -using Examine; using LightInject; using Umbraco.Core; using Umbraco.Core.Components; using Umbraco.Core.Configuration; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.DI; using Umbraco.Core.Dictionary; using Umbraco.Core.Events; @@ -235,28 +233,10 @@ namespace Umbraco.Web UmbracoConfig.For.UmbracoSettings(), urlProviders); - // rebuild any empty indexes - // do we want to make this optional? otherwise the only way to disable this on startup - // would be to implement a custom WebBootManager and override this method - // fixme - move to its own component! and then it could be disabled >> ExamineComponent - // fixme - configuration? - if (runtime.Level == RuntimeLevel.Run) - RebuildIndexes(true); - // ensure WebAPI is initialized, after everything GlobalConfiguration.Configuration.EnsureInitialized(); } - // fixme - this should move to something else, we should not depend on Examine here! - private static void RebuildIndexes(bool onlyEmptyIndexes) - { - var indexers = (IEnumerable>)ExamineManager.Instance.IndexProviders; - if (onlyEmptyIndexes) - indexers = indexers.Where(x => x.Value.IsIndexNew()); - foreach (var indexer in indexers) - indexer.Value.RebuildIndex(); - } - private static void ConfigureGlobalFilters() { GlobalFilters.Filters.Add(new EnsurePartialViewMacroViewContextFilterAttribute());