Bugfix exception during install, live models collision
This commit is contained in:
@@ -30,7 +30,7 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
protected override IComponent CreateItem(IFactory factory, Type itemType)
|
||||
{
|
||||
using (_logger.DebugDuration<Composers>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
using (_logger.DebugDuration<ComponentCollectionBuilder>($"Creating {itemType.FullName}.", $"Created {itemType.FullName}.", thresholdMilliseconds: LogThresholdMilliseconds))
|
||||
{
|
||||
return base.CreateItem(factory, itemType);
|
||||
}
|
||||
|
||||
33
src/Umbraco.Core/PublishedModelFactoryExtensions.cs
Normal file
33
src/Umbraco.Core/PublishedModelFactoryExtensions.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="IPublishedModelFactory"/>.
|
||||
/// </summary>
|
||||
public static class PublishedModelFactoryExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Executes an action with a safe live factory/
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>If the factory is a live factory, ensures it is refreshed and locked while executing the action.</para>
|
||||
/// </remarks>
|
||||
public static void WithSafeLiveFactory(this IPublishedModelFactory factory, Action action)
|
||||
{
|
||||
if (factory is ILivePublishedModelFactory liveFactory)
|
||||
{
|
||||
lock (liveFactory.SyncRoot)
|
||||
{
|
||||
liveFactory.Refresh();
|
||||
action();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,6 +212,7 @@
|
||||
<Compile Include="Models\PublishedContent\ILivePublishedModelFactory.cs" />
|
||||
<Compile Include="PropertyEditors\DateTimeConfiguration.cs" />
|
||||
<Compile Include="Migrations\Upgrade\V_8_0_0\RenameLabelAndRichTextPropertyEditorAliases.cs" />
|
||||
<Compile Include="PublishedModelFactoryExtensions.cs" />
|
||||
<Compile Include="Services\PropertyValidationService.cs" />
|
||||
<Compile Include="TypeLoaderExtensions.cs" />
|
||||
<Compile Include="Composing\WeightAttribute.cs" />
|
||||
|
||||
@@ -180,8 +180,8 @@ namespace Umbraco.Tests.PublishedContent
|
||||
dataSource,
|
||||
globalSettings,
|
||||
new SiteDomainHelper(),
|
||||
contentTypeServiceBaseFactory,
|
||||
Mock.Of<IEntityXmlSerializer>());
|
||||
Mock.Of<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
|
||||
// invariant is the current default
|
||||
_variationAccesor.VariationContext = new VariationContext();
|
||||
|
||||
@@ -97,8 +97,9 @@ namespace Umbraco.Tests.Scoping
|
||||
documentRepository, mediaRepository, memberRepository,
|
||||
DefaultCultureAccessor,
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(), contentTypeServiceBaseFactory,
|
||||
Factory.GetInstance<IEntityXmlSerializer>());
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
}
|
||||
|
||||
protected UmbracoContext GetUmbracoContextNu(string url, int templateId = 1234, RouteData routeData = null, bool setSingleton = false, IUmbracoSettingsSection umbracoSettings = null, IEnumerable<IUrlProvider> urlProviders = null)
|
||||
|
||||
@@ -70,8 +70,9 @@ namespace Umbraco.Tests.Services
|
||||
documentRepository, mediaRepository, memberRepository,
|
||||
DefaultCultureAccessor,
|
||||
new DatabaseDataSource(),
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(), contentTypeServiceBaseFactory,
|
||||
Factory.GetInstance<IEntityXmlSerializer>());
|
||||
Factory.GetInstance<IGlobalSettings>(), new SiteDomainHelper(),
|
||||
Factory.GetInstance<IEntityXmlSerializer>(),
|
||||
Mock.Of<IPublishedModelFactory>());
|
||||
}
|
||||
|
||||
public class LocalServerMessenger : ServerMessengerBase
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
@@ -82,20 +83,8 @@ namespace Umbraco.Web.Cache
|
||||
// service of changes, else factories may try to rebuild models while
|
||||
// we are using the database to load content into caches
|
||||
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
if (_publishedModelFactory is ILivePublishedModelFactory live)
|
||||
{
|
||||
lock (live.SyncRoot)
|
||||
{
|
||||
live.Refresh();
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ReSharper disable once InconsistentlySynchronizedField
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
// now we can trigger the event
|
||||
base.Refresh(payloads);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
@@ -65,20 +66,8 @@ namespace Umbraco.Web.Cache
|
||||
// service of changes, else factories may try to rebuild models while
|
||||
// we are using the database to load content into caches
|
||||
|
||||
// ReSharper disable once SuspiciousTypeConversion.Global
|
||||
if (_publishedModelFactory is ILivePublishedModelFactory live)
|
||||
{
|
||||
lock (live.SyncRoot)
|
||||
{
|
||||
live.Refresh();
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ReSharper disable once InconsistentlySynchronizedField
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
}
|
||||
_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private readonly IMemberRepository _memberRepository;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly ISiteDomainHelper _siteDomainHelper;
|
||||
private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
|
||||
private readonly IEntityXmlSerializer _entitySerializer;
|
||||
private readonly IDefaultCultureAccessor _defaultCultureAccessor;
|
||||
private readonly IPublishedModelFactory _publishedModelFactory;
|
||||
|
||||
// volatile because we read it with no lock
|
||||
private volatile bool _isReady;
|
||||
@@ -88,8 +88,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IScopeProvider scopeProvider,
|
||||
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
|
||||
IDefaultCultureAccessor defaultCultureAccessor,
|
||||
IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider,
|
||||
IEntityXmlSerializer entitySerializer)
|
||||
IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper,
|
||||
IEntityXmlSerializer entitySerializer, IPublishedModelFactory publishedModelFactory)
|
||||
: base(publishedSnapshotAccessor, variationContextAccessor)
|
||||
{
|
||||
//if (Interlocked.Increment(ref _singletonCheck) > 1)
|
||||
@@ -107,7 +107,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_defaultCultureAccessor = defaultCultureAccessor;
|
||||
_globalSettings = globalSettings;
|
||||
_siteDomainHelper = siteDomainHelper;
|
||||
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider;
|
||||
_publishedModelFactory = publishedModelFactory;
|
||||
|
||||
// we need an Xml serializer here so that the member cache can support XPath,
|
||||
// for members this is done by navigating the serialized-to-xml member
|
||||
@@ -167,7 +167,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
_domainStore = new SnapDictionary<int, Domain>();
|
||||
|
||||
LoadCaches();
|
||||
_publishedModelFactory.WithSafeLiveFactory(LoadCaches);
|
||||
|
||||
Guid GetUid(ContentStore store, int id) => store.LiveSnapshot.Get(id)?.Uid ?? default;
|
||||
int GetId(ContentStore store, Guid uid) => store.LiveSnapshot.Get(uid)?.Id ?? default;
|
||||
@@ -571,6 +571,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// because now we should ALWAYS run with the database server messenger, and then the RefreshAll will
|
||||
// be processed as soon as we are configured and the messenger processes instructions.
|
||||
|
||||
// note: notifications for content type and data type changes should be invoked with the
|
||||
// pure live model factory, if any, locked and refreshed - see ContentTypeCacheRefresher and
|
||||
// DataTypeCacheRefresher
|
||||
|
||||
public override void Notify(ContentCacheRefresher.JsonPayload[] payloads, out bool draftChanged, out bool publishedChanged)
|
||||
{
|
||||
// no cache, trash everything
|
||||
|
||||
Reference in New Issue
Block a user