Merge remote-tracking branch 'origin/netcore/netcore' into netcore/feature/migrate-logging
Signed-off-by: Bjarke Berg <mail@bergmania.dk> # Conflicts: # src/Umbraco.Infrastructure/Search/ExamineComponent.cs # src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs
This commit is contained in:
@@ -5,6 +5,7 @@ using System.Linq;
|
||||
using Examine;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Scoping;
|
||||
@@ -14,9 +15,12 @@ using Umbraco.Core.Sync;
|
||||
using Umbraco.Web.Cache;
|
||||
using Umbraco.Examine;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Web.Scheduling;
|
||||
|
||||
namespace Umbraco.Web.Search
|
||||
{
|
||||
|
||||
|
||||
public sealed class ExamineComponent : Umbraco.Core.Composing.IComponent
|
||||
{
|
||||
private readonly IExamineManager _examineManager;
|
||||
@@ -31,7 +35,7 @@ namespace Umbraco.Web.Search
|
||||
private readonly IProfilingLogger _pLogger;
|
||||
private readonly Microsoft.Extensions.Logging.ILogger<ExamineComponent> _logger;
|
||||
private readonly IUmbracoIndexesCreator _indexCreator;
|
||||
|
||||
private readonly BackgroundTaskRunner<IBackgroundTask> _indexItemTaskRunner;
|
||||
|
||||
// the default enlist priority is 100
|
||||
// enlist with a lower priority to ensure that anything "default" runs after us
|
||||
@@ -39,15 +43,16 @@ namespace Umbraco.Web.Search
|
||||
private const int EnlistPriority = 80;
|
||||
|
||||
public ExamineComponent(IMainDom mainDom,
|
||||
IExamineManager examineManager, IProfilingLogger profilingLogger,
|
||||
Microsoft.Extensions.Logging.ILogger<ExamineComponent> logger,
|
||||
IExamineManager examineManager, IProfilingLogger profilingLogger,
|
||||
ILoggerFactory loggerFactory,
|
||||
IScopeProvider scopeProvider, IUmbracoIndexesCreator indexCreator,
|
||||
ServiceContext services,
|
||||
IContentValueSetBuilder contentValueSetBuilder,
|
||||
IPublishedContentValueSetBuilder publishedContentValueSetBuilder,
|
||||
IValueSetBuilder<IMedia> mediaValueSetBuilder,
|
||||
IValueSetBuilder<IMember> memberValueSetBuilder,
|
||||
BackgroundIndexRebuilder backgroundIndexRebuilder)
|
||||
BackgroundIndexRebuilder backgroundIndexRebuilder,
|
||||
IApplicationShutdownRegistry applicationShutdownRegistry)
|
||||
{
|
||||
_services = services;
|
||||
_scopeProvider = scopeProvider;
|
||||
@@ -59,8 +64,9 @@ namespace Umbraco.Web.Search
|
||||
_backgroundIndexRebuilder = backgroundIndexRebuilder;
|
||||
_mainDom = mainDom;
|
||||
_pLogger = profilingLogger;
|
||||
_logger = logger;
|
||||
_logger = loggerFactory.CreateLogger<ExamineComponent>();
|
||||
_indexCreator = indexCreator;
|
||||
_indexItemTaskRunner = new BackgroundTaskRunner<IBackgroundTask>(loggerFactory.CreateLogger<BackgroundTaskRunner<IBackgroundTask>>(), applicationShutdownRegistry);
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
@@ -566,12 +572,18 @@ namespace Umbraco.Web.Search
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An action that will execute at the end of the Scope being completed
|
||||
/// </summary>
|
||||
private abstract class DeferedAction
|
||||
{
|
||||
public virtual void Execute()
|
||||
{ }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-indexes an <see cref="IContent"/> item on a background thread
|
||||
/// </summary>
|
||||
private class DeferedReIndexForContent : DeferedAction
|
||||
{
|
||||
private readonly ExamineComponent _examineComponent;
|
||||
@@ -592,41 +604,32 @@ namespace Umbraco.Web.Search
|
||||
|
||||
public static void Execute(ExamineComponent examineComponent, IContent content, bool isPublished)
|
||||
{
|
||||
// TODO: This is ugly, it is going to build the value set 3x and for 2 of those times it will be the same value
|
||||
// set. We can do better.
|
||||
|
||||
// TODO: We are .ToList() ing each of the calls to GetValueSets here. This is currently required but isn't the way
|
||||
// that this was intended to work. Ideally, the IEnumerable package gets passed to Examine and it is only iterated/executed
|
||||
// when the indexing takes place which would occur on a background thread. This is problematic with how the ContentValueSetBuilder
|
||||
// in combination with UmbracoContentIndex.PerformIndexItems works because (at least what I've come to believe) we are using yield
|
||||
// return in the GetValueSets call in combination with trying to lazily resolve the enumerable but because we GroupBy in
|
||||
// UmbracoContentIndex.PerformIndexItems it's eagerly executed but then lazily executed again on the background thread and I believe
|
||||
// that in doing this when the call is made to _userService.GetProfilesById it's trying to resolve a scope from an AsyncLocal instance
|
||||
// that has already been disposed higher up it's chain. I 'think' to how the eager/lazy enumeration happens with yield return that it's
|
||||
// capturing a scope/AsyncLocal instance that it shouldn't really be using.
|
||||
|
||||
// TODO: We don't want these value sets to be eagerly built in this thread since this is most likely going to be a request thread.
|
||||
// This is why the lazy execution of the Enumerable had the intended affect of executing only when requested on the background thread.
|
||||
// This could still be acheived: Either we have a custom Enumerable/Enumerator to do this, or we simply call the below code
|
||||
// on a background thread... which would be much easier!
|
||||
|
||||
// TODO: I think this is an issue in v8 too!
|
||||
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => isPublished || !x.PublishedValuesOnly)
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
// perform the ValueSet lookup on a background thread
|
||||
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
|
||||
{
|
||||
//for content we have a different builder for published vs unpublished
|
||||
var builder = index.PublishedValuesOnly
|
||||
? examineComponent._publishedContentValueSetBuilder
|
||||
: (IValueSetBuilder<IContent>)examineComponent._contentValueSetBuilder;
|
||||
// for content we have a different builder for published vs unpublished
|
||||
// we don't want to build more value sets than is needed so we'll lazily build 2 one for published one for non-published
|
||||
var builders = new Dictionary<bool, Lazy<List<ValueSet>>>
|
||||
{
|
||||
[true] = new Lazy<List<ValueSet>>(() => examineComponent._publishedContentValueSetBuilder.GetValueSets(content).ToList()),
|
||||
[false] = new Lazy<List<ValueSet>>(() => examineComponent._contentValueSetBuilder.GetValueSets(content).ToList())
|
||||
};
|
||||
|
||||
index.IndexItems(builder.GetValueSets(content).ToList());
|
||||
}
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => isPublished || !x.PublishedValuesOnly)
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
{
|
||||
var valueSet = builders[index.PublishedValuesOnly].Value;
|
||||
index.IndexItems(valueSet);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-indexes an <see cref="IMedia"/> item on a background thread
|
||||
/// </summary>
|
||||
private class DeferedReIndexForMedia : DeferedAction
|
||||
{
|
||||
private readonly ExamineComponent _examineComponent;
|
||||
@@ -647,18 +650,25 @@ namespace Umbraco.Web.Search
|
||||
|
||||
public static void Execute(ExamineComponent examineComponent, IMedia media, bool isPublished)
|
||||
{
|
||||
var valueSet = examineComponent._mediaValueSetBuilder.GetValueSets(media).ToList();
|
||||
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => isPublished || !x.PublishedValuesOnly)
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
// perform the ValueSet lookup on a background thread
|
||||
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
|
||||
{
|
||||
index.IndexItems(valueSet);
|
||||
}
|
||||
var valueSet = examineComponent._mediaValueSetBuilder.GetValueSets(media).ToList();
|
||||
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => isPublished || !x.PublishedValuesOnly)
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
{
|
||||
index.IndexItems(valueSet);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-indexes an <see cref="IMember"/> item on a background thread
|
||||
/// </summary>
|
||||
private class DeferedReIndexForMember : DeferedAction
|
||||
{
|
||||
private readonly ExamineComponent _examineComponent;
|
||||
@@ -677,13 +687,17 @@ namespace Umbraco.Web.Search
|
||||
|
||||
public static void Execute(ExamineComponent examineComponent, IMember member)
|
||||
{
|
||||
var valueSet = examineComponent._memberValueSetBuilder.GetValueSets(member).ToList();
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
// perform the ValueSet lookup on a background thread
|
||||
examineComponent._indexItemTaskRunner.Add(new SimpleTask(() =>
|
||||
{
|
||||
index.IndexItems(valueSet);
|
||||
}
|
||||
var valueSet = examineComponent._memberValueSetBuilder.GetValueSets(member).ToList();
|
||||
foreach (var index in examineComponent._examineManager.Indexes.OfType<IUmbracoIndex>()
|
||||
//filter the indexers
|
||||
.Where(x => x.EnableDefaultEventHandler))
|
||||
{
|
||||
index.IndexItems(valueSet);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user