Adds ext methods for creating a flag to indicate model recompilation should occur
This commit is contained in:
@@ -25,15 +25,7 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
|
||||
// get model
|
||||
// if factory returns nothing, throw
|
||||
var model = Current.PublishedModelFactory.CreateModel(content);
|
||||
if (model == null)
|
||||
throw new Exception("Factory returned null.");
|
||||
|
||||
// if factory returns a different type, throw
|
||||
if (!(model is IPublishedContent publishedContent))
|
||||
throw new Exception($"Factory returned model of type {model.GetType().FullName} which does not implement IPublishedContent.");
|
||||
|
||||
return publishedContent;
|
||||
return Current.PublishedModelFactory.CreateModelWithSafeLiveFactoryRefreshCheck(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,62 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a strongly typed model while checking if the factory is <see cref="ILivePublishedModelFactory"/> and if a refresh flag has been set, in which
|
||||
/// case the models will be recompiled before model creation
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
internal static IPublishedContent CreateModelWithSafeLiveFactoryRefreshCheck(this IPublishedModelFactory factory, IPublishedContent content)
|
||||
{
|
||||
if (factory is ILivePublishedModelFactory liveFactory && _refresh)
|
||||
{
|
||||
lock (liveFactory.SyncRoot)
|
||||
{
|
||||
if (_refresh)
|
||||
{
|
||||
_refresh = false;
|
||||
//Call refresh on the live factory to re-compile the models
|
||||
liveFactory.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var model = factory.CreateModel(content);
|
||||
if (model == null)
|
||||
throw new Exception("Factory returned null.");
|
||||
|
||||
// if factory returns a different type, throw
|
||||
if (!(model is IPublishedContent publishedContent))
|
||||
throw new Exception($"Factory returned model of type {model.GetType().FullName} which does not implement IPublishedContent.");
|
||||
|
||||
return publishedContent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a flag to re-compile the models if the <see cref="IPublishedModelFactory"/> is <see cref="ILivePublishedModelFactory"/>
|
||||
/// </summary>
|
||||
/// <param name="factory"></param>
|
||||
/// <param name="action"></param>
|
||||
internal static void WithSafeLiveFactoryRefreshSet(this IPublishedModelFactory factory, Action action)
|
||||
{
|
||||
if (factory is ILivePublishedModelFactory liveFactory)
|
||||
{
|
||||
lock (liveFactory.SyncRoot)
|
||||
{
|
||||
_refresh = true;
|
||||
action();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
action();
|
||||
}
|
||||
}
|
||||
|
||||
private static volatile bool _refresh = false;
|
||||
|
||||
public static IDisposable SuspendSafeLiveFactory(this IPublishedModelFactory factory)
|
||||
{
|
||||
if (factory is ILivePublishedModelFactory liveFactory)
|
||||
|
||||
@@ -91,7 +91,8 @@ namespace Umbraco.Web.Cache
|
||||
// we are using the database to load content into caches
|
||||
|
||||
//_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
_publishedModelFactory.WithSafeLiveFactoryRefreshSet(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
// now we can trigger the event
|
||||
base.Refresh(payloads);
|
||||
|
||||
@@ -67,7 +67,8 @@ namespace Umbraco.Web.Cache
|
||||
// we are using the database to load content into caches
|
||||
|
||||
//_publishedModelFactory.WithSafeLiveFactory(() =>
|
||||
_publishedSnapshotService.Notify(payloads);
|
||||
_publishedModelFactory.WithSafeLiveFactoryRefreshSet(() =>
|
||||
_publishedSnapshotService.Notify(payloads));
|
||||
|
||||
base.Refresh(payloads);
|
||||
}
|
||||
|
||||
@@ -790,22 +790,23 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
Notify<IContentType>(_contentStore, payloads, RefreshContentTypesLocked);
|
||||
Notify<IMediaType>(_mediaStore, payloads, RefreshMediaTypesLocked);
|
||||
|
||||
//TODO: I don't think this is necessary with the changes to nucache now that calls to `CreateModel` are lazy!
|
||||
//if (_publishedModelFactory.IsLiveFactory())
|
||||
//{
|
||||
// //In the case of Pure Live - we actually need to refresh all of the content and the media
|
||||
// //see https://github.com/umbraco/Umbraco-CMS/issues/5671
|
||||
// //The underlying issue is that in Pure Live the ILivePublishedModelFactory will re-compile all of the classes/models
|
||||
// //into a new DLL for the application which includes both content types and media types.
|
||||
// //Since the models in the cache are based on these actual classes, all of the objects in the cache need to be updated
|
||||
// //to use the newest version of the class.
|
||||
// using (_contentStore.GetScopedWriteLock(_scopeProvider))
|
||||
// using (_mediaStore.GetScopedWriteLock(_scopeProvider))
|
||||
// {
|
||||
// NotifyLocked(new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out var draftChanged, out var publishedChanged);
|
||||
// NotifyLocked(new[] { new MediaCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out var anythingChanged);
|
||||
// }
|
||||
//}
|
||||
//TODO: I don't think this is necessary with the changes to nucache now that calls to `CreateModel` are lazy?
|
||||
// but I may be dreaming here, if i remove this call and save a content type, then the cache doesn't render a lot of the content. hrm.
|
||||
if (_publishedModelFactory.IsLiveFactory())
|
||||
{
|
||||
//In the case of Pure Live - we actually need to refresh all of the content and the media
|
||||
//see https://github.com/umbraco/Umbraco-CMS/issues/5671
|
||||
//The underlying issue is that in Pure Live the ILivePublishedModelFactory will re-compile all of the classes/models
|
||||
//into a new DLL for the application which includes both content types and media types.
|
||||
//Since the models in the cache are based on these actual classes, all of the objects in the cache need to be updated
|
||||
//to use the newest version of the class.
|
||||
using (_contentStore.GetScopedWriteLock(_scopeProvider))
|
||||
using (_mediaStore.GetScopedWriteLock(_scopeProvider))
|
||||
{
|
||||
NotifyLocked(new[] { new ContentCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out var draftChanged, out var publishedChanged);
|
||||
NotifyLocked(new[] { new MediaCacheRefresher.JsonPayload(0, TreeChangeTypes.RefreshAll) }, out var anythingChanged);
|
||||
}
|
||||
}
|
||||
|
||||
((PublishedSnapshot)CurrentPublishedSnapshot)?.Resync();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user