diff --git a/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj b/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj
index 2f2bb5866d..454a6cf2ce 100644
--- a/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj
+++ b/src/SQLCE4Umbraco/SqlCE4Umbraco.csproj
@@ -49,11 +49,9 @@
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll
- True
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll
- True
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 340a7ae6d8..e52720b574 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -39,22 +39,18 @@
..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll
- True
..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll
- True
..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll
..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll
- True
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
- True
..\packages\ImageProcessor.2.5.6\lib\net45\ImageProcessor.dll
@@ -67,11 +63,9 @@
..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
- True
..\packages\Microsoft.AspNet.Identity.Owin.2.2.1\lib\net45\Microsoft.AspNet.Identity.Owin.dll
- True
..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll
@@ -87,17 +81,16 @@
..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll
- True
..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll
+ True
..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll
..\packages\Owin.1.0\lib\net40\Owin.dll
- True
..\packages\semver.1.1.2\lib\net45\Semver.dll
@@ -109,11 +102,9 @@
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll
- True
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll
- True
diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
index 64fef90ffa..6cad6893f5 100644
--- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
+++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
@@ -40,34 +40,27 @@
..\packages\BenchmarkDotNet.0.9.9\lib\net45\BenchmarkDotNet.dll
- True
..\packages\BenchmarkDotNet.Core.0.9.9\lib\net45\BenchmarkDotNet.Core.dll
- True
..\packages\BenchmarkDotNet.Diagnostics.Windows.0.9.9\lib\net45\BenchmarkDotNet.Diagnostics.Windows.dll
- True
..\packages\BenchmarkDotNet.Toolchains.Roslyn.0.9.9\lib\net45\BenchmarkDotNet.Toolchains.Roslyn.dll
- True
..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll
..\packages\Microsoft.CodeAnalysis.Common.1.3.2\lib\net45\Microsoft.CodeAnalysis.dll
- True
..\packages\Microsoft.CodeAnalysis.CSharp.1.3.2\lib\net45\Microsoft.CodeAnalysis.CSharp.dll
- True
..\packages\Microsoft.Diagnostics.Tracing.TraceEvent.1.0.41\lib\net40\Microsoft.Diagnostics.Tracing.TraceEvent.dll
- True
..\packages\Moq.4.1.1309.0919\lib\net40\Moq.dll
@@ -75,27 +68,22 @@
..\packages\System.Collections.Immutable.1.2.0\lib\portable-net45+win8+wp8+wpa81\System.Collections.Immutable.dll
- True
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll
- True
..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll
- True
..\packages\System.Reflection.Metadata.1.3.0\lib\portable-net45+win8\System.Reflection.Metadata.dll
- True
..\packages\System.Threading.Tasks.Extensions.4.0.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll
- True
@@ -116,6 +104,7 @@
+
@@ -132,8 +121,8 @@
-
-
+
+
diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj
index 3fd09fc532..935731f00a 100644
--- a/src/Umbraco.Tests/Umbraco.Tests.csproj
+++ b/src/Umbraco.Tests/Umbraco.Tests.csproj
@@ -62,8 +62,8 @@
..\packages\Castle.Core.4.0.0\lib\net45\Castle.Core.dll
-
- ..\packages\Examine.0.1.88\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.89-beta05\lib\net45\Examine.dll
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config
index 921ac155c7..6075f6da6d 100644
--- a/src/Umbraco.Tests/packages.config
+++ b/src/Umbraco.Tests/packages.config
@@ -2,7 +2,7 @@
-
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index bfca512100..9bad128cc6 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -127,11 +127,10 @@
..\packages\dotless.1.5.2\lib\dotless.Core.dll
-
- ..\packages\Examine.0.1.88\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.89-beta05\lib\net45\Examine.dll
- False
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
@@ -144,7 +143,6 @@
..\packages\log4net.2.0.8\lib\net45-full\log4net.dll
- False
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config
index a17f6414ed..a87caf5199 100644
--- a/src/Umbraco.Web.UI/packages.config
+++ b/src/Umbraco.Web.UI/packages.config
@@ -4,7 +4,7 @@
-
+
diff --git a/src/Umbraco.Web/ExamineStartup.cs b/src/Umbraco.Web/ExamineStartup.cs
new file mode 100644
index 0000000000..c8cc83663c
--- /dev/null
+++ b/src/Umbraco.Web/ExamineStartup.cs
@@ -0,0 +1,175 @@
+using System.Collections.Generic;
+using System.Linq;
+using Examine;
+using Examine.Config;
+using Examine.LuceneEngine;
+using Examine.LuceneEngine.Providers;
+using Examine.Providers;
+using Lucene.Net.Index;
+using Lucene.Net.Store;
+using Umbraco.Core;
+using Umbraco.Core.Logging;
+using UmbracoExamine;
+
+namespace Umbraco.Web
+{
+ ///
+ /// Used to configure Examine during startup for the web application
+ ///
+ internal class ExamineStartup
+ {
+ private readonly List _indexesToRebuild = new List();
+ private readonly ApplicationContext _appCtx;
+ private readonly ProfilingLogger _profilingLogger;
+
+ //this is used if we are not the MainDom, in which case we need to ensure that if indexes need rebuilding that this
+ //doesn't occur since that should only occur when we are MainDom
+ private bool _disableExamineIndexing = false;
+
+ public ExamineStartup(ApplicationContext appCtx)
+ {
+ _appCtx = appCtx;
+ _profilingLogger = appCtx.ProfilingLogger;
+ }
+
+ ///
+ /// Called during the initialize operation of the boot manager process
+ ///
+ public void Initialize()
+ {
+ //We want to manage Examine's appdomain shutdown sequence ourselves so first we'll disable Examine's default behavior
+ //and then we'll use MainDom to control Examine's shutdown
+ ExamineManager.DisableDefaultHostingEnvironmentRegistration();
+
+ //we want to tell examine to use a different fs lock instead of the default NativeFSFileLock which could cause problems if the appdomain
+ //terminates and in some rare cases would only allow unlocking of the file if IIS is forcefully terminated. Instead we'll rely on the simplefslock
+ //which simply checks the existence of the lock file
+ DirectoryTracker.DefaultLockFactory = d =>
+ {
+ var simpleFsLockFactory = new NoPrefixSimpleFsLockFactory(d);
+ return simpleFsLockFactory;
+ };
+
+ //This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
+ // when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
+ // event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
+ // it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
+ // boot process has completed. It's a hack but it works.
+ ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup;
+
+ //let's deal with shutting down Examine with MainDom
+ var examineShutdownRegistered = _appCtx.MainDom.Register(() =>
+ {
+ using (_profilingLogger.TraceDuration("Examine shutting down"))
+ {
+ //Due to the way Examine's own IRegisteredObject works, we'll first run it with immediate=false and then true so that
+ //it's correct subroutines are executed (otherwise we'd have to run this logic manually ourselves)
+ ExamineManager.Instance.Stop(false);
+ ExamineManager.Instance.Stop(true);
+ }
+ });
+ if (examineShutdownRegistered)
+ {
+ _profilingLogger.Logger.Debug("Examine shutdown registered with MainDom");
+ }
+ else
+ {
+ _profilingLogger.Logger.Debug("Examine shutdown not registered, this appdomain is not the MainDom");
+
+ //if we could not register the shutdown examine ourselves, it means we are not maindom! in this case all of examine should be disabled
+ //from indexing anything on startup!!
+ _disableExamineIndexing = true;
+ }
+ }
+
+ ///
+ /// Called during the Complete operation of the boot manager process
+ ///
+ public void Complete()
+ {
+ //We now need to disable waiting for indexing for Examine so that the appdomain is shutdown immediately and doesn't wait for pending
+ //indexing operations. We used to wait for indexing operations to complete but this can cause more problems than that is worth because
+ //that could end up halting shutdown for a very long time causing overlapping appdomains and many other problems.
+ foreach (var luceneIndexer in ExamineManager.Instance.IndexProviderCollection.OfType())
+ {
+ luceneIndexer.WaitForIndexQueueOnShutdown = false;
+ }
+
+ //Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
+ // (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
+ // initialize during startup, in which case we want it to rebuild the indexes itself.
+ ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
+
+ //don't do anything if we have disabled this
+ if (_disableExamineIndexing == false)
+ {
+ foreach (var indexer in _indexesToRebuild)
+ {
+ indexer.RebuildIndex();
+ }
+ }
+ }
+
+ ///
+ /// Called to perform the rebuilding indexes on startup if the indexes don't exist
+ ///
+ public void RebuildIndexes()
+ {
+ //don't do anything if we have disabled this
+ if (_disableExamineIndexing) return;
+
+ //If the developer has explicitly opted out of rebuilding indexes on startup then we
+ // should adhere to that and not do it, this means that if they are load balancing things will be
+ // out of sync if they are auto-scaling but there's not much we can do about that.
+ if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
+
+ foreach (var indexer in GetIndexesForColdBoot())
+ {
+ indexer.RebuildIndex();
+ }
+ }
+
+ ///
+ /// The method used to create indexes on a cold boot
+ ///
+ ///
+ /// A cold boot is when the server determines it will not (or cannot) process instructions in the cache table and
+ /// will rebuild it's own caches itself.
+ ///
+ public IEnumerable GetIndexesForColdBoot()
+ {
+ // NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
+ // on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty.
+ // This callback is used above for the DatabaseServerMessenger startup options.
+
+ // all indexes
+ IEnumerable indexes = ExamineManager.Instance.IndexProviderCollection;
+
+ // except those that are already flagged
+ // and are processed in Complete()
+ if (_indexesToRebuild.Any())
+ indexes = indexes.Except(_indexesToRebuild);
+
+ // return
+ foreach (var index in indexes)
+ yield return index;
+ }
+
+ private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
+ {
+ //store the indexer that needs rebuilding because it's empty for when the boot process
+ // is complete and cancel this current event so the rebuild process doesn't start right now.
+ args.Cancel = true;
+ _indexesToRebuild.Add((BaseIndexProvider)args.Indexer);
+
+ //check if the index is rebuilding due to an error and log it
+ if (args.IsHealthy == false)
+ {
+ var baseIndex = args.Indexer as BaseIndexProvider;
+ var name = baseIndex != null ? baseIndex.Name : "[UKNOWN]";
+
+ _profilingLogger.Logger.Error(string.Format("The index {0} is rebuilding due to being unreadable/corrupt", name), args.UnhealthyException);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index aa54d7b369..b3fb40608e 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -112,8 +112,8 @@
..\packages\dotless.1.5.2\lib\dotless.Core.dll
-
- ..\packages\Examine.0.1.88\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.89-beta05\lib\net45\Examine.dll
..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll
@@ -121,11 +121,9 @@
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
- True
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
- True
..\packages\Markdown.1.14.7\lib\net45\MarkdownSharp.dll
@@ -333,6 +331,7 @@
+
diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs
index 2f6b81820f..c38540b6a2 100644
--- a/src/Umbraco.Web/WebBootManager.cs
+++ b/src/Umbraco.Web/WebBootManager.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Linq;
-using System.Reflection;
using System.Web;
using System.Web.Configuration;
using System.Web.Http;
@@ -11,10 +10,7 @@ using System.Web.Http.Dispatcher;
using System.Web.Mvc;
using System.Web.Routing;
using ClientDependency.Core.Config;
-using Examine;
-using Examine.Config;
using Examine.Providers;
-using umbraco;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Dictionary;
@@ -27,25 +23,18 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Core.Sync;
using Umbraco.Web.Dictionary;
using Umbraco.Web.Install;
-using Umbraco.Web.Macros;
using Umbraco.Web.Media;
using Umbraco.Web.Media.ThumbnailProviders;
-using Umbraco.Web.Models;
using Umbraco.Web.Mvc;
-using Umbraco.Web.PropertyEditors;
-using Umbraco.Web.PropertyEditors.ValueConverters;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Security;
-using Umbraco.Web.Scheduling;
using Umbraco.Web.UI.JavaScript;
using Umbraco.Web.WebApi;
-using umbraco.BusinessLogic;
using Umbraco.Core.Cache;
using Umbraco.Core.Events;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
-using Umbraco.Core.Publishing;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using Umbraco.Web.Editors;
@@ -64,8 +53,9 @@ namespace Umbraco.Web
public class WebBootManager : CoreBootManager
{
private readonly bool _isForTesting;
- //NOTE: see the Initialize method for what this is used for
- private static readonly List IndexesToRebuild = new List();
+
+ //needs to be static because we have the public static method GetIndexesForColdBoot
+ private static ExamineStartup _examineStartup;
public WebBootManager(UmbracoApplicationBase umbracoApplication)
: base(umbracoApplication)
@@ -109,15 +99,11 @@ namespace Umbraco.Web
///
public override IBootManager Initialize()
{
- //This is basically a hack for this item: http://issues.umbraco.org/issue/U4-5976
- // when Examine initializes it will try to rebuild if the indexes are empty, however in many cases not all of Examine's
- // event handlers will be assigned during bootup when the rebuilding starts which is a problem. So with the examine 0.1.58.2941 build
- // it has an event we can subscribe to in order to cancel this rebuilding process, but what we'll do is cancel it and postpone the rebuilding until the
- // boot process has completed. It's a hack but it works.
- ExamineManager.Instance.BuildingEmptyIndexOnStartup += OnInstanceOnBuildingEmptyIndexOnStartup;
-
base.Initialize();
+ _examineStartup = new ExamineStartup(ApplicationContext);
+ _examineStartup.Initialize();
+
// Backwards compatibility - set the path and URL type for ClientDependency 1.5.1 [LK]
ClientDependency.Core.CompositeFiles.Providers.XmlFileMapper.FileMapVirtualFolder = "~/App_Data/TEMP/ClientDependency";
ClientDependency.Core.CompositeFiles.Providers.BaseCompositeFileProcessingProvider.UrlTypeDefault = ClientDependency.Core.CompositeFiles.Providers.CompositeUrlType.Base64QueryStrings;
@@ -214,25 +200,15 @@ namespace Umbraco.Web
//Now, startup all of our legacy startup handler
ApplicationEventsResolver.Current.InstantiateLegacyStartupHandlers();
- //Ok, now that everything is complete we'll check if we've stored any references to index that need rebuilding and run them
- // (see the initialize method for notes) - we'll ensure we remove the event handler too in case examine manager doesn't actually
- // initialize during startup, in which case we want it to rebuild the indexes itself.
- ExamineManager.Instance.BuildingEmptyIndexOnStartup -= OnInstanceOnBuildingEmptyIndexOnStartup;
- if (IndexesToRebuild.Any())
- {
- foreach (var indexer in IndexesToRebuild)
- {
- indexer.RebuildIndex();
- }
- }
+ _examineStartup.Complete();
//Now ensure webapi is initialized after everything
GlobalConfiguration.Configuration.EnsureInitialized();
-
+
return this;
}
-
+
internal static void ConfigureGlobalFilters()
{
@@ -377,11 +353,11 @@ namespace Umbraco.Web
{
base.InitializeResolvers();
- SearchableTreeResolver.Current = new SearchableTreeResolver(ServiceProvider, LoggerResolver.Current.Logger, ApplicationContext.Services.ApplicationTreeService, () => PluginManager.ResolveSearchableTrees());
+ SearchableTreeResolver.Current = new SearchableTreeResolver(ServiceProvider, LoggerResolver.Current.Logger, ApplicationContext.Services.ApplicationTreeService, () => PluginManager.ResolveSearchableTrees());
XsltExtensionsResolver.Current = new XsltExtensionsResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveXsltExtensions());
- EditorValidationResolver.Current= new EditorValidationResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveTypes());
+ EditorValidationResolver.Current = new EditorValidationResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveTypes());
//set the default RenderMvcController
DefaultRenderMvcControllerResolver.Current = new DefaultRenderMvcControllerResolver(typeof(RenderMvcController));
@@ -421,23 +397,6 @@ namespace Umbraco.Web
}
else
{
-
- //We are using a custom action here so we can check the examine settings value first, we don't want to
- // put that check into the CreateIndexesOnColdBoot method because developers may choose to use this
- // method directly and they will be in charge of this check if they need it
- Action rebuildIndexes = () =>
- {
- //If the developer has explicitly opted out of rebuilding indexes on startup then we
- // should adhere to that and not do it, this means that if they are load balancing things will be
- // out of sync if they are auto-scaling but there's not much we can do about that.
- if (ExamineSettings.Instance.RebuildOnAppStart == false) return;
-
- foreach (var indexer in GetIndexesForColdBoot())
- {
- indexer.RebuildIndex();
- }
- };
-
ServerMessengerResolver.Current.SetServerMessenger(new BatchedDatabaseServerMessenger(
ApplicationContext,
true,
@@ -453,7 +412,7 @@ namespace Umbraco.Web
//rebuild indexes if the server is not synced
// NOTE: This will rebuild ALL indexes including the members, if developers want to target specific
// indexes then they can adjust this logic themselves.
- rebuildIndexes
+ () => _examineStartup.RebuildIndexes()
}
}));
}
@@ -489,9 +448,9 @@ namespace Umbraco.Web
// add all known factories, devs can then modify this list on application
// startup either by binding to events or in their own global.asax
new[]
- {
- typeof (RenderControllerFactory)
- });
+ {
+ typeof (RenderControllerFactory)
+ });
UrlProviderResolver.Current = new UrlProviderResolver(
ServiceProvider, LoggerResolver.Current.Logger,
@@ -559,42 +518,11 @@ namespace Umbraco.Web
///
/// A cold boot is when the server determines it will not (or cannot) process instructions in the cache table and
/// will rebuild it's own caches itself.
+ /// TODO: Does this method need to exist? Is it used publicly elsewhere (i.e. outside of core?)
///
public static IEnumerable GetIndexesForColdBoot()
{
- // NOTE: This is IMPORTANT! ... we don't want to rebuild any index that is already flagged to be re-indexed
- // on startup based on our _indexesToRebuild variable and how Examine auto-rebuilds when indexes are empty.
- // This callback is used above for the DatabaseServerMessenger startup options.
-
- // all indexes
- IEnumerable indexes = ExamineManager.Instance.IndexProviderCollection;
-
- // except those that are already flagged
- // and are processed in Complete()
- if (IndexesToRebuild.Any())
- indexes = indexes.Except(IndexesToRebuild);
-
- // return
- foreach (var index in indexes)
- yield return index;
- }
-
-
- private void OnInstanceOnBuildingEmptyIndexOnStartup(object sender, BuildingEmptyIndexOnStartupEventArgs args)
- {
- //store the indexer that needs rebuilding because it's empty for when the boot process
- // is complete and cancel this current event so the rebuild process doesn't start right now.
- args.Cancel = true;
- IndexesToRebuild.Add((BaseIndexProvider)args.Indexer);
-
- //check if the index is rebuilding due to an error and log it
- if (args.IsHealthy == false)
- {
- var baseIndex = args.Indexer as BaseIndexProvider;
- var name = baseIndex != null ? baseIndex.Name : "[UKNOWN]";
-
- ProfilingLogger.Logger.Error(string.Format("The index {0} is rebuilding due to being unreadable/corrupt", name), args.UnhealthyException);
- }
+ return _examineStartup.GetIndexesForColdBoot();
}
}
}
diff --git a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
index ca49f7a9f7..1218ddc2da 100644
--- a/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
+++ b/src/Umbraco.Web/WebServices/ExamineManagementApiController.cs
@@ -8,7 +8,9 @@ using Examine;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Examine.Providers;
+using Lucene.Net.Index;
using Lucene.Net.Search;
+using Lucene.Net.Store;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Web.Search;
@@ -189,20 +191,39 @@ namespace Umbraco.Web.WebServices
{
indexer.RebuildIndex();
}
+ catch (LockObtainFailedException)
+ {
+ //this will occur if the index is locked (which it should defo not be!) so in this case we'll forcibly unlock it and try again
+
+ try
+ {
+ IndexWriter.Unlock(indexer.GetLuceneDirectory());
+ indexer.RebuildIndex();
+ }
+ catch (Exception e)
+ {
+ return HandleException(e, indexer);
+ }
+ }
catch (Exception ex)
{
- //ensure it's not listening
- indexer.IndexOperationComplete -= Indexer_IndexOperationComplete;
- LogHelper.Error("An error occurred rebuilding index", ex);
- var response = Request.CreateResponse(HttpStatusCode.Conflict);
- response.Content = new StringContent(string.Format("The index could not be rebuilt at this time, most likely there is another thread currently writing to the index. Error: {0}", ex));
- response.ReasonPhrase = "Could Not Rebuild";
- return response;
+ return HandleException(ex, indexer);
}
}
return msg;
}
+ private HttpResponseMessage HandleException(Exception ex, LuceneIndexer indexer)
+ {
+ //ensure it's not listening
+ indexer.IndexOperationComplete -= Indexer_IndexOperationComplete;
+ LogHelper.Error("An error occurred rebuilding index", ex);
+ var response = Request.CreateResponse(HttpStatusCode.Conflict);
+ response.Content = new StringContent(string.Format("The index could not be rebuilt at this time, most likely there is another thread currently writing to the index. Error: {0}", ex));
+ response.ReasonPhrase = "Could Not Rebuild";
+ return response;
+ }
+
//static listener so it's not GC'd
private static void Indexer_IndexOperationComplete(object sender, EventArgs e)
{
diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config
index 905b005fe4..689b56c87e 100644
--- a/src/Umbraco.Web/packages.config
+++ b/src/Umbraco.Web/packages.config
@@ -3,7 +3,7 @@
-
+
diff --git a/src/UmbracoExamine/NoPrefixSimpleFsLockFactory.cs b/src/UmbracoExamine/NoPrefixSimpleFsLockFactory.cs
new file mode 100644
index 0000000000..ac4210bcc0
--- /dev/null
+++ b/src/UmbracoExamine/NoPrefixSimpleFsLockFactory.cs
@@ -0,0 +1,26 @@
+using System.IO;
+using Examine;
+using Examine.LuceneEngine;
+using Lucene.Net.Store;
+
+namespace UmbracoExamine
+{
+ ///
+ /// A custom that ensures a prefixless lock prefix
+ ///
+ ///
+ /// This is a work around for the Lucene APIs. By default Lucene will use a null prefix however when we set a custom
+ /// lock factory the null prefix is overwritten.
+ ///
+ public class NoPrefixSimpleFsLockFactory : SimpleFSLockFactory
+ {
+ public NoPrefixSimpleFsLockFactory(DirectoryInfo lockDir) : base(lockDir)
+ {
+ }
+
+ public override void SetLockPrefix(string lockPrefix)
+ {
+ base.SetLockPrefix(null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/UmbracoExamine/UmbracoContentIndexer.cs b/src/UmbracoExamine/UmbracoContentIndexer.cs
index 2a2e2ce98c..649c18df47 100644
--- a/src/UmbracoExamine/UmbracoContentIndexer.cs
+++ b/src/UmbracoExamine/UmbracoContentIndexer.cs
@@ -410,7 +410,11 @@ namespace UmbracoExamine
{
if (SupportedTypes.Contains(type) == false)
return;
-
+
+ //if the app is shutting down do not continue
+ if (IsCancellationRequested)
+ return;
+
var pageIndex = 0;
DataService.LogService.AddInfoLog(-1, string.Format("PerformIndexAll - Start data queries - {0}", type));
@@ -530,7 +534,7 @@ namespace UmbracoExamine
content, notPublished).WhereNotNull(), type);
pageIndex++;
- } while (currentPageSize == PageSize);
+ } while (currentPageSize == PageSize && IsCancellationRequested == false); //do not continue if app is shutting down
}
break;
@@ -628,7 +632,7 @@ namespace UmbracoExamine
AddNodesToIndex(xElements, type);
pageIndex++;
- } while (more);
+ } while (more && IsCancellationRequested == false); //don't continue if the app is shutting down
}
internal static IEnumerable GetSerializedContent(
diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj
index 015fc923cb..2c46c156ef 100644
--- a/src/UmbracoExamine/UmbracoExamine.csproj
+++ b/src/UmbracoExamine/UmbracoExamine.csproj
@@ -82,16 +82,14 @@
..\Solution Items\TheFARM-Public.snk
-
- ..\packages\Examine.0.1.88\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.89-beta05\lib\net45\Examine.dll
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
- True
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
- True
@@ -136,6 +134,7 @@
+
diff --git a/src/UmbracoExamine/UmbracoMemberIndexer.cs b/src/UmbracoExamine/UmbracoMemberIndexer.cs
index 8aa6a49d5a..f3ee7a4a89 100644
--- a/src/UmbracoExamine/UmbracoMemberIndexer.cs
+++ b/src/UmbracoExamine/UmbracoMemberIndexer.cs
@@ -197,7 +197,7 @@ namespace UmbracoExamine
AddNodesToIndex(GetSerializedMembers(members), type);
pageIndex++;
- } while (members.Length == pageSize);
+ } while (members.Length == pageSize && IsCancellationRequested == false); //don't continue if the app is shutting down
}
}
else
@@ -211,7 +211,7 @@ namespace UmbracoExamine
AddNodesToIndex(GetSerializedMembers(members), type);
pageIndex++;
- } while (members.Length == pageSize);
+ } while (members.Length == pageSize && IsCancellationRequested == false); //don't continue if the app is shutting down
}
}
}
diff --git a/src/UmbracoExamine/packages.config b/src/UmbracoExamine/packages.config
index 40bdd28e84..74b8cbb907 100644
--- a/src/UmbracoExamine/packages.config
+++ b/src/UmbracoExamine/packages.config
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config
index 6aadcba8d4..14c21a4bd4 100644
--- a/src/umbraco.MacroEngines/packages.config
+++ b/src/umbraco.MacroEngines/packages.config
@@ -1,6 +1,6 @@
-
+
diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
index d9734abfd8..bde18c31dd 100644
--- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
+++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj
@@ -45,8 +45,8 @@
false
-
- ..\packages\Examine.0.1.88\lib\net45\Examine.dll
+
+ ..\packages\Examine.0.1.89-beta05\lib\net45\Examine.dll
..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll
@@ -54,11 +54,9 @@
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
- True
..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll
- True
..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
diff --git a/src/umbraco.businesslogic/umbraco.businesslogic.csproj b/src/umbraco.businesslogic/umbraco.businesslogic.csproj
index bbc98ca0c7..cb1e47eaf8 100644
--- a/src/umbraco.businesslogic/umbraco.businesslogic.csproj
+++ b/src/umbraco.businesslogic/umbraco.businesslogic.csproj
@@ -108,11 +108,9 @@
..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll
- True
..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll
- True
..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
@@ -122,11 +120,9 @@
..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
- True
..\packages\Owin.1.0\lib\net40\Owin.dll
- True
@@ -145,27 +141,21 @@
..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll
- True
..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll
- True
..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll
- True
..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll
- True
..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll
- True
..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll
- True
System.XML
diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj
index 554cd0b969..e2baba7ada 100644
--- a/src/umbraco.cms/umbraco.cms.csproj
+++ b/src/umbraco.cms/umbraco.cms.csproj
@@ -108,15 +108,12 @@
..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll
- True
..\packages\HtmlAgilityPack.1.4.9.5\lib\Net45\HtmlAgilityPack.dll
- True
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
- True
@@ -168,7 +165,6 @@
..\packages\Tidy.Net.1.0.0\lib\TidyNet.dll
- True
diff --git a/src/umbraco.controls/umbraco.controls.csproj b/src/umbraco.controls/umbraco.controls.csproj
index e458a56213..c562fa35d1 100644
--- a/src/umbraco.controls/umbraco.controls.csproj
+++ b/src/umbraco.controls/umbraco.controls.csproj
@@ -70,7 +70,6 @@
..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll
- True
diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj
index e0fd450022..de34a0cfbb 100644
--- a/src/umbraco.datalayer/umbraco.datalayer.csproj
+++ b/src/umbraco.datalayer/umbraco.datalayer.csproj
@@ -70,10 +70,10 @@
..\packages\Microsoft.ApplicationBlocks.Data.1.0.1559.20655\lib\Microsoft.ApplicationBlocks.Data.dll
- True
..\packages\MySql.Data.6.9.9\lib\net45\MySql.Data.dll
+ True
diff --git a/src/umbraco.editorControls/umbraco.editorControls.csproj b/src/umbraco.editorControls/umbraco.editorControls.csproj
index 5950ac9719..602187e55a 100644
--- a/src/umbraco.editorControls/umbraco.editorControls.csproj
+++ b/src/umbraco.editorControls/umbraco.editorControls.csproj
@@ -116,7 +116,6 @@
..\packages\ClientDependency.1.9.2\lib\net45\ClientDependency.Core.dll
- True
System