renames objects/methods and adds a lock to the routing mechanism
This commit is contained in:
@@ -46,7 +46,11 @@ namespace Umbraco.Tests.Routing
|
||||
logger,
|
||||
null, // FIXME: PublishedRouter complexities...
|
||||
Mock.Of<IVariationContextAccessor>(),
|
||||
Mock.Of<IUmbracoContextFactory>()
|
||||
Mock.Of<IUmbracoContextFactory>(),
|
||||
new Umbraco.Web.Cache.BackgroundPublishedSnapshotServiceNotifier(
|
||||
Factory.GetInstance<IPublishedModelFactory>(),
|
||||
Factory.GetInstance<IPublishedSnapshotService>(),
|
||||
Logger)
|
||||
);
|
||||
|
||||
runtime.Level = RuntimeLevel.Run;
|
||||
|
||||
@@ -8,29 +8,62 @@ using Umbraco.Web.Scheduling;
|
||||
|
||||
namespace Umbraco.Web.Cache
|
||||
{
|
||||
public sealed class BackgroundSafeLiveFactory
|
||||
/// <summary>
|
||||
/// Used to notify the <see cref="IPublishedSnapshotService"/> of changes using a background thread
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When in Pure Live mode, the models need to be rebuilt before the IPublishedSnapshotService is notified which can result in performance penalties so
|
||||
/// this performs these actions on a background thread so the user isn't waiting for the rebuilding to occur on a UI thread.
|
||||
/// </remarks>
|
||||
public sealed class BackgroundPublishedSnapshotServiceNotifier
|
||||
{
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
private readonly IPublishedSnapshotService _publishedSnapshotService;
|
||||
private BackgroundTaskRunner<IBackgroundTask> _runner;
|
||||
private readonly BackgroundTaskRunner<IBackgroundTask> _runner;
|
||||
|
||||
public BackgroundSafeLiveFactory(IPublishedModelFactory publishedModelFactory, IPublishedSnapshotService publishedSnapshotService, ILogger logger)
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="publishedModelFactory"></param>
|
||||
/// <param name="publishedSnapshotService"></param>
|
||||
/// <param name="logger"></param>
|
||||
public BackgroundPublishedSnapshotServiceNotifier(IPublishedModelFactory publishedModelFactory, IPublishedSnapshotService publishedSnapshotService, ILogger logger)
|
||||
{
|
||||
_publishedModelFactory = publishedModelFactory;
|
||||
_publishedSnapshotService = publishedSnapshotService;
|
||||
|
||||
// TODO: We have the option to check if we are in live mode and only run on a background thread if that is the case, else run normally?
|
||||
// IMO I think we should just always run on a background thread, then no matter what state the app is in, it's always doing a consistent operation.
|
||||
|
||||
_runner = new BackgroundTaskRunner<IBackgroundTask>("RebuildModelsAndCache", logger);
|
||||
}
|
||||
|
||||
public void Execute(ContentTypeCacheRefresher.JsonPayload[] payloads)
|
||||
/// <summary>
|
||||
/// Blocks until the background operation is completed
|
||||
/// </summary>
|
||||
public void Wait() => _runner.StoppedAwaitable.GetAwaiter().GetResult(); //TODO: do we need a try/catch?
|
||||
|
||||
/// <summary>
|
||||
/// Notify the <see cref="IPublishedSnapshotService"/> of content type changes
|
||||
/// </summary>
|
||||
/// <param name="payloads"></param>
|
||||
public void NotifyWithSafeLiveFactory(ContentTypeCacheRefresher.JsonPayload[] payloads)
|
||||
{
|
||||
_runner.TryAdd(new RebuildModelsAndCacheTask(payloads, _publishedModelFactory, _publishedSnapshotService));
|
||||
}
|
||||
|
||||
public void Execute(DataTypeCacheRefresher.JsonPayload[] payloads)
|
||||
/// <summary>
|
||||
/// Notify the <see cref="IPublishedSnapshotService"/> of data type changes
|
||||
/// </summary>
|
||||
/// <param name="payloads"></param>
|
||||
public void NotifyWithSafeLiveFactory(DataTypeCacheRefresher.JsonPayload[] payloads)
|
||||
{
|
||||
_runner.TryAdd(new RebuildModelsAndCacheTask(payloads, _publishedModelFactory, _publishedSnapshotService));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A simple background task that notifies the <see cref="IPublishedSnapshotService"/> of changes
|
||||
/// </summary>
|
||||
private class RebuildModelsAndCacheTask : IBackgroundTask
|
||||
{
|
||||
private readonly DataTypeCacheRefresher.JsonPayload[] _dataTypePayloads;
|
||||
@@ -71,10 +104,7 @@ namespace Umbraco.Web.Cache
|
||||
});
|
||||
}
|
||||
|
||||
public Task RunAsync(CancellationToken token)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
public Task RunAsync(CancellationToken token) => throw new System.NotImplementedException();
|
||||
|
||||
public bool IsAsync => false;
|
||||
|
||||
@@ -10,11 +10,11 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
public sealed class ContentTypeCacheRefresher : PayloadCacheRefresherBase<ContentTypeCacheRefresher, ContentTypeCacheRefresher.JsonPayload>
|
||||
{
|
||||
private readonly BackgroundSafeLiveFactory _backgroundModelFactory;
|
||||
private readonly BackgroundPublishedSnapshotServiceNotifier _backgroundModelFactory;
|
||||
private readonly IContentTypeCommonRepository _contentTypeCommonRepository;
|
||||
private readonly IdkMap _idkMap;
|
||||
|
||||
public ContentTypeCacheRefresher(AppCaches appCaches, BackgroundSafeLiveFactory backgroundModelFactory, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository)
|
||||
public ContentTypeCacheRefresher(AppCaches appCaches, BackgroundPublishedSnapshotServiceNotifier backgroundModelFactory, IdkMap idkMap, IContentTypeCommonRepository contentTypeCommonRepository)
|
||||
: base(appCaches)
|
||||
{
|
||||
_backgroundModelFactory = backgroundModelFactory;
|
||||
@@ -80,7 +80,7 @@ namespace Umbraco.Web.Cache
|
||||
MemberCacheRefresher.RefreshMemberTypes(AppCaches);
|
||||
|
||||
// refresh the models and cache
|
||||
_backgroundModelFactory.Execute(payloads);
|
||||
_backgroundModelFactory.NotifyWithSafeLiveFactory(payloads);
|
||||
|
||||
// now we can trigger the event
|
||||
base.Refresh(payloads);
|
||||
|
||||
@@ -9,10 +9,10 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
public sealed class DataTypeCacheRefresher : PayloadCacheRefresherBase<DataTypeCacheRefresher, DataTypeCacheRefresher.JsonPayload>
|
||||
{
|
||||
private readonly BackgroundSafeLiveFactory _backgroundModelFactory;
|
||||
private readonly BackgroundPublishedSnapshotServiceNotifier _backgroundModelFactory;
|
||||
private readonly IdkMap _idkMap;
|
||||
|
||||
public DataTypeCacheRefresher(AppCaches appCaches, BackgroundSafeLiveFactory backgroundModelFactory, IdkMap idkMap)
|
||||
public DataTypeCacheRefresher(AppCaches appCaches, BackgroundPublishedSnapshotServiceNotifier backgroundModelFactory, IdkMap idkMap)
|
||||
: base(appCaches)
|
||||
{
|
||||
_backgroundModelFactory = backgroundModelFactory;
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Web.Cache
|
||||
SliderValueConverter.ClearCaches();
|
||||
|
||||
// refresh the models and cache
|
||||
_backgroundModelFactory.Execute(payloads);
|
||||
_backgroundModelFactory.NotifyWithSafeLiveFactory(payloads);
|
||||
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Compose;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Services.Changes;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Umbraco.Web.Runtime
|
||||
// register distributed cache
|
||||
composition.RegisterUnique(f => new DistributedCache());
|
||||
|
||||
composition.RegisterUnique<BackgroundSafeLiveFactory>();
|
||||
composition.RegisterUnique<BackgroundPublishedSnapshotServiceNotifier>();
|
||||
|
||||
// replace some services
|
||||
composition.RegisterUnique<IEventMessagesFactory, DefaultEventMessagesFactory>();
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
<Compile Include="AppBuilderExtensions.cs" />
|
||||
<Compile Include="AreaRegistrationContextExtensions.cs" />
|
||||
<Compile Include="AspNetHttpContextAccessor.cs" />
|
||||
<Compile Include="Cache\BackgroundSafeLiveFactory.cs" />
|
||||
<Compile Include="Cache\BackgroundPublishedSnapshotServiceNotifier.cs" />
|
||||
<Compile Include="Cache\DistributedCacheBinder.cs" />
|
||||
<Compile Include="Cache\DistributedCacheBinderComposer.cs" />
|
||||
<Compile Include="Cache\DistributedCacheBinder_Handlers.cs" />
|
||||
|
||||
@@ -18,6 +18,7 @@ using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.Cache;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
@@ -48,6 +49,7 @@ namespace Umbraco.Web
|
||||
private readonly IPublishedRouter _publishedRouter;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IUmbracoContextFactory _umbracoContextFactory;
|
||||
private readonly BackgroundPublishedSnapshotServiceNotifier _backgroundNotifier;
|
||||
|
||||
public UmbracoInjectedModule(
|
||||
IGlobalSettings globalSettings,
|
||||
@@ -59,7 +61,8 @@ namespace Umbraco.Web
|
||||
ILogger logger,
|
||||
IPublishedRouter publishedRouter,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextFactory umbracoContextFactory)
|
||||
IUmbracoContextFactory umbracoContextFactory,
|
||||
BackgroundPublishedSnapshotServiceNotifier backgroundNotifier)
|
||||
{
|
||||
_combinedRouteCollection = new Lazy<RouteCollection>(CreateRouteCollection);
|
||||
|
||||
@@ -73,6 +76,7 @@ namespace Umbraco.Web
|
||||
_publishedRouter = publishedRouter;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_umbracoContextFactory = umbracoContextFactory;
|
||||
_backgroundNotifier = backgroundNotifier;
|
||||
}
|
||||
|
||||
#region HttpModule event handlers
|
||||
@@ -136,6 +140,10 @@ namespace Umbraco.Web
|
||||
// do not process if this request is not a front-end routable page
|
||||
var isRoutableAttempt = EnsureUmbracoRoutablePage(umbracoContext, httpContext);
|
||||
|
||||
// If this page is probably front-end routable, block here until the backround notifier isn't busy
|
||||
if (isRoutableAttempt)
|
||||
_backgroundNotifier.Wait();
|
||||
|
||||
// raise event here
|
||||
UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext, httpContext));
|
||||
if (isRoutableAttempt.Success == false) return;
|
||||
|
||||
Reference in New Issue
Block a user