New IPublishedSnapshotStatus, reduces IPublishedSnapshotService
This commit is contained in:
@@ -1352,7 +1352,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// reading _floorGen is safe if _collectTask is null
|
||||
if (_collectTask == null && _collectAuto && _liveGen - _floorGen > CollectMinGenDelta)
|
||||
{
|
||||
CollectAsyncLocked();
|
||||
}
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
@@ -1374,8 +1376,17 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
private Task CollectAsyncLocked()
|
||||
{
|
||||
// NOTE: What in the heck is going on here? Why is any of this running in async contexts?
|
||||
// SD: From what I can tell this was designed to be a set and forget background task to do the
|
||||
// collecting which is why it's called from non-async methods within this class. This is
|
||||
// slightly dangerous because it's not taking into account app shutdown.
|
||||
// TODO: There should be a different method or class responsible for executing the cleanup on a
|
||||
// background (set and forget) thread.
|
||||
|
||||
if (_collectTask != null)
|
||||
{
|
||||
return _collectTask;
|
||||
}
|
||||
|
||||
// ReSharper disable InconsistentlySynchronizedField
|
||||
var task = _collectTask = Task.Run((Action)Collect);
|
||||
|
||||
@@ -27,6 +27,10 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
builder.Services.AddTransient(factory => new PublishedSnapshotServiceOptions());
|
||||
builder.SetPublishedSnapshotService<PublishedSnapshotService>();
|
||||
|
||||
// Add as itself
|
||||
builder.Services.AddSingleton<PublishedSnapshotService>();
|
||||
builder.Services.AddSingleton<IPublishedSnapshotStatus, PublishedSnapshotStatus>();
|
||||
|
||||
// replace this service since we want to improve the content/media
|
||||
// mapping lookups if we are using nucache.
|
||||
// TODO: Gotta wonder how much this does actually improve perf? It's a lot of weird code to make this happen so hope it's worth it
|
||||
|
||||
@@ -94,14 +94,26 @@ namespace Umbraco.Infrastructure.PublishedCache.Persistence
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool VerifyContentDbCache()
|
||||
=> _repository.VerifyContentDbCache();
|
||||
{
|
||||
using IScope scope = ScopeProvider.CreateScope(autoComplete: true);
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
return _repository.VerifyContentDbCache();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool VerifyMediaDbCache()
|
||||
=> _repository.VerifyMediaDbCache();
|
||||
{
|
||||
using IScope scope = ScopeProvider.CreateScope(autoComplete: true);
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
return _repository.VerifyMediaDbCache();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool VerifyMemberDbCache()
|
||||
=> _repository.VerifyMemberDbCache();
|
||||
{
|
||||
using IScope scope = ScopeProvider.CreateScope(autoComplete: true);
|
||||
scope.ReadLock(Constants.Locks.MemberTree);
|
||||
return _repository.VerifyMemberDbCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CSharpTest.Net.Collections;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -47,7 +48,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly NuCacheSettings _config;
|
||||
|
||||
// volatile because we read it with no lock
|
||||
private bool _isReady;
|
||||
private bool _isReadSet;
|
||||
private object _isReadyLock;
|
||||
@@ -264,7 +264,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
/// <summary>
|
||||
/// Populates the stores
|
||||
/// </summary>
|
||||
private void EnsureCaches() => LazyInitializer.EnsureInitialized(
|
||||
internal void EnsureCaches() => LazyInitializer.EnsureInitialized(
|
||||
ref _isReady,
|
||||
ref _isReadSet,
|
||||
ref _isReadyLock,
|
||||
@@ -914,7 +914,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// some may be missing - not checking here
|
||||
|
||||
return contentTypes.Select(x => _publishedContentTypeFactory.CreateContentType(x)).ToList();
|
||||
}
|
||||
|
||||
@@ -950,7 +949,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// content (and content types) are read-locked while reading content
|
||||
// contentStore is wlocked (so readable, only no new views)
|
||||
// and it can be wlocked by 1 thread only at a time
|
||||
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTypes);
|
||||
@@ -989,7 +987,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// media (and content types) are read-locked while reading media
|
||||
// mediaStore is wlocked (so readable, only no new views)
|
||||
// and it can be wlocked by 1 thread only at a time
|
||||
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTypes);
|
||||
@@ -1047,7 +1044,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// nothing like that...
|
||||
// for elements cache, DictionaryAppCache is a No-No, use something better.
|
||||
// ie FastDictionaryAppCache (thread safe and all)
|
||||
|
||||
ContentStore.Snapshot contentSnap, mediaSnap;
|
||||
SnapDictionary<int, Domain>.Snapshot domainSnap;
|
||||
IAppCache elementsCache;
|
||||
@@ -1059,7 +1055,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
lock (_elementsLock)
|
||||
{
|
||||
var scopeContext = _scopeProvider.Context;
|
||||
IScopeContext scopeContext = _scopeProvider.Context;
|
||||
|
||||
if (scopeContext == null)
|
||||
{
|
||||
@@ -1089,7 +1085,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}, int.MaxValue);
|
||||
}
|
||||
|
||||
|
||||
// create a new snapshot cache if snapshots are different gens
|
||||
if (contentSnap.Gen != _contentGen || mediaSnap.Gen != _mediaGen || domainSnap.Gen != _domainGen || _elementsCache == null)
|
||||
{
|
||||
@@ -1126,75 +1121,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
IReadOnlyCollection<int> memberTypeIds = null)
|
||||
=> _publishedContentService.Rebuild(groupSize, contentTypeIds, mediaTypeIds, memberTypeIds);
|
||||
|
||||
public bool VerifyContentDbCache()
|
||||
{
|
||||
// TODO: Shouldn't this entire logic just exist in the call to _publishedContentService?
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.ContentTree);
|
||||
var ok = _publishedContentService.VerifyContentDbCache();
|
||||
scope.Complete();
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
public bool VerifyMediaDbCache()
|
||||
{
|
||||
// TODO: Shouldn't this entire logic just exist in the call to _publishedContentService?
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MediaTree);
|
||||
var ok = _publishedContentService.VerifyMediaDbCache();
|
||||
scope.Complete();
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
public bool VerifyMemberDbCache()
|
||||
{
|
||||
// TODO: Shouldn't this entire logic just exist in the call to _publishedContentService?
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
{
|
||||
scope.ReadLock(Constants.Locks.MemberTree);
|
||||
var ok = _publishedContentService.VerifyMemberDbCache();
|
||||
scope.Complete();
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetStatus()
|
||||
public async Task CollectAsync()
|
||||
{
|
||||
EnsureCaches();
|
||||
|
||||
var dbCacheIsOk = VerifyContentDbCache()
|
||||
&& VerifyMediaDbCache()
|
||||
&& VerifyMemberDbCache();
|
||||
|
||||
var cg = _contentStore.GenCount;
|
||||
var mg = _mediaStore.GenCount;
|
||||
var cs = _contentStore.SnapCount;
|
||||
var ms = _mediaStore.SnapCount;
|
||||
var ce = _contentStore.Count;
|
||||
var me = _mediaStore.Count;
|
||||
|
||||
return
|
||||
" Database cache is " + (dbCacheIsOk ? "ok" : "NOT ok (rebuild?)") + "." +
|
||||
" ContentStore contains " + ce + " item" + (ce > 1 ? "s" : "") +
|
||||
" and has " + cg + " generation" + (cg > 1 ? "s" : "") +
|
||||
" and " + cs + " snapshot" + (cs > 1 ? "s" : "") + "." +
|
||||
" MediaStore contains " + me + " item" + (ce > 1 ? "s" : "") +
|
||||
" and has " + mg + " generation" + (mg > 1 ? "s" : "") +
|
||||
" and " + ms + " snapshot" + (ms > 1 ? "s" : "") + ".";
|
||||
}
|
||||
|
||||
// TODO: This should be async since it's calling into async
|
||||
public void Collect()
|
||||
{
|
||||
EnsureCaches();
|
||||
|
||||
var contentCollect = _contentStore.CollectAsync();
|
||||
var mediaCollect = _mediaStore.CollectAsync();
|
||||
System.Threading.Tasks.Task.WaitAll(contentCollect, mediaCollect);
|
||||
await _contentStore.CollectAsync();
|
||||
await _mediaStore.CollectAsync();
|
||||
}
|
||||
|
||||
internal ContentStore GetContentStore()
|
||||
@@ -1209,9 +1141,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return _mediaStore;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual string StatusUrl => "views/dashboard/settings/publishedsnapshotcache.html";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{ }
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
using Umbraco.Infrastructure.PublishedCache.Persistence;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates a status report for <see cref="PublishedSnapshotService"/>
|
||||
/// </summary>
|
||||
internal class PublishedSnapshotStatus : IPublishedSnapshotStatus
|
||||
{
|
||||
private readonly PublishedSnapshotService _service;
|
||||
private readonly INuCacheContentService _publishedContentService;
|
||||
|
||||
public PublishedSnapshotStatus(PublishedSnapshotService service, INuCacheContentService publishedContentService)
|
||||
{
|
||||
_service = service;
|
||||
_publishedContentService = publishedContentService;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public virtual string StatusUrl => "views/dashboard/settings/publishedsnapshotcache.html";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public string GetStatus()
|
||||
{
|
||||
_service.EnsureCaches();
|
||||
|
||||
var dbCacheIsOk = _publishedContentService.VerifyContentDbCache()
|
||||
&& _publishedContentService.VerifyMediaDbCache()
|
||||
&& _publishedContentService.VerifyMemberDbCache();
|
||||
|
||||
ContentStore contentStore = _service.GetContentStore();
|
||||
ContentStore mediaStore = _service.GetMediaStore();
|
||||
|
||||
var cg = contentStore.GenCount;
|
||||
var mg = mediaStore.GenCount;
|
||||
var cs = contentStore.SnapCount;
|
||||
var ms = mediaStore.SnapCount;
|
||||
var ce = contentStore.Count;
|
||||
var me = mediaStore.Count;
|
||||
|
||||
return
|
||||
" Database cache is " + (dbCacheIsOk ? "ok" : "NOT ok (rebuild?)") + "." +
|
||||
" ContentStore contains " + ce + " item" + (ce > 1 ? "s" : "") +
|
||||
" and has " + cg + " generation" + (cg > 1 ? "s" : "") +
|
||||
" and " + cs + " snapshot" + (cs > 1 ? "s" : "") + "." +
|
||||
" MediaStore contains " + me + " item" + (ce > 1 ? "s" : "") +
|
||||
" and has " + mg + " generation" + (mg > 1 ? "s" : "") +
|
||||
" and " + ms + " snapshot" + (ms > 1 ? "s" : "") + ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user