diff --git a/src/Umbraco.Examine/ExamineExtensions.cs b/src/Umbraco.Examine/ExamineExtensions.cs index 3681979267..71e3e65c21 100644 --- a/src/Umbraco.Examine/ExamineExtensions.cs +++ b/src/Umbraco.Examine/ExamineExtensions.cs @@ -1,8 +1,11 @@ using System; +using System.Linq; +using Examine; using Examine.LuceneEngine.Providers; using Lucene.Net.Index; using Lucene.Net.Search; using Lucene.Net.Store; +using Umbraco.Core.Logging; namespace Umbraco.Examine { @@ -11,6 +14,32 @@ namespace Umbraco.Examine /// internal static class ExamineExtensions { + /// + /// Forcibly unlocks all lucene based indexes + /// + /// + /// This is not thread safe, use with care + /// + internal static void UnlockLuceneIndexes(this IExamineManager examineManager, ILogger logger) + { + foreach (var luceneIndexer in examineManager.Indexes.OfType()) + { + //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. + luceneIndexer.WaitForIndexQueueOnShutdown = false; + + //we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that + //the indexes are not operational unless MainDom is true + var dir = luceneIndexer.GetLuceneDirectory(); + if (IndexWriter.IsLocked(dir)) + { + logger.Info(typeof(ExamineExtensions), "Forcing index {IndexerName} to be unlocked since it was left in a locked state", luceneIndexer.Name); + IndexWriter.Unlock(dir); + } + } + } + /// /// Checks if the index can be read/opened /// diff --git a/src/Umbraco.Examine/Properties/AssemblyInfo.cs b/src/Umbraco.Examine/Properties/AssemblyInfo.cs index 6713111968..5c42a236f4 100644 --- a/src/Umbraco.Examine/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Examine/Properties/AssemblyInfo.cs @@ -8,6 +8,7 @@ using System.Runtime.CompilerServices; // Umbraco Cms [assembly: InternalsVisibleTo("Umbraco.Tests")] +[assembly: InternalsVisibleTo("Umbraco.Web")] // code analysis // IDE1006 is broken, wants _value syntax for consts, etc - and it's even confusing ppl at MS, kill it diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index 508a005663..d14ffb5001 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -106,12 +106,11 @@ namespace Umbraco.Tests.PublishedContent Assert.AreEqual("
This is some content
", propVal2.ToString()); var propVal3 = publishedMedia.Value("Content"); - Assert.IsInstanceOf(propVal3); + Assert.IsInstanceOf(propVal3); Assert.AreEqual("
This is some content
", propVal3.ToString()); } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void Ensure_Children_Sorted_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -119,7 +118,9 @@ namespace Umbraco.Tests.PublishedContent using (var luceneDir = new RandomIdRamDirectory()) using (var indexer = IndexInitializer.GetUmbracoIndexer(ProfilingLogger, luceneDir, validator: new ContentValueSetValidator(true))) + using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var searcher = indexer.GetSearcher(); @@ -139,7 +140,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void Do_Not_Find_In_Recycle_Bin() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -150,6 +150,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var searcher = indexer.GetSearcher(); @@ -187,7 +188,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void Children_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -197,6 +197,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var searcher = indexer.GetSearcher(); @@ -215,7 +216,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void Descendants_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -225,6 +225,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var searcher = indexer.GetSearcher(); @@ -243,7 +244,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void DescendantsOrSelf_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -253,6 +253,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var searcher = indexer.GetSearcher(); @@ -271,7 +272,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void Ancestors_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -282,6 +282,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); var ctx = GetUmbracoContext("/test"); @@ -297,7 +298,6 @@ namespace Umbraco.Tests.PublishedContent } [Test] - [Ignore("No point testing with Examine, should refactor this test.")] public void AncestorsOrSelf_With_Examine() { var rebuilder = IndexInitializer.GetMediaIndexRebuilder(Container.GetInstance(), IndexInitializer.GetMockMediaService()); @@ -307,6 +307,7 @@ namespace Umbraco.Tests.PublishedContent validator: new ContentValueSetValidator(true))) using (indexer.ProcessNonAsync()) { + rebuilder.RegisterIndex(indexer.Name); rebuilder.Populate(indexer); diff --git a/src/Umbraco.Web/Search/ExamineComponent.cs b/src/Umbraco.Web/Search/ExamineComponent.cs index d8c1016c3e..f2d3168b45 100644 --- a/src/Umbraco.Web/Search/ExamineComponent.cs +++ b/src/Umbraco.Web/Search/ExamineComponent.cs @@ -219,23 +219,7 @@ namespace Umbraco.Web.Search if (_isConfigured) return; _isConfigured = true; - - foreach (var luceneIndexer in examineManager.Indexes.OfType()) - { - //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. - luceneIndexer.WaitForIndexQueueOnShutdown = false; - - //we should check if the index is locked ... it shouldn't be! We are using simple fs lock now and we are also ensuring that - //the indexes are not operational unless MainDom is true - var dir = luceneIndexer.GetLuceneDirectory(); - if (IndexWriter.IsLocked(dir)) - { - logger.Info("Forcing index {IndexerName} to be unlocked since it was left in a locked state", luceneIndexer.Name); - IndexWriter.Unlock(dir); - } - } + examineManager.UnlockLuceneIndexes(logger); } }