Port v7@2aa0dfb2c5 - WIP

This commit is contained in:
Stephan
2018-03-27 10:51:41 +02:00
parent 0a4878d2a3
commit d40a835701
25 changed files with 363 additions and 171 deletions

View File

@@ -486,7 +486,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
// not trying to be thread-safe here, that's not the point
if (preview == false)
{
// if there's a current enlisted reader/writer, use its xml
var tempXml = _xmlStore.TempXml;
if (tempXml != null) return tempXml;
return _xml;
}
// Xml cache does not support retrieving preview content when not previewing
if (_previewContent == null)

View File

@@ -108,7 +108,43 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
public override IEnumerable<IPublishedContent> GetAtRoot(bool preview)
{
//TODO: We should be able to look these ids first in Examine!
var searchProvider = GetSearchProviderSafe();
if (searchProvider != null)
{
try
{
// first check in Examine for the cache values
// +(+parentID:-1) +__IndexType:media
var criteria = searchProvider.CreateSearchCriteria("media");
var filter = criteria.ParentId(-1).Not().Field(UmbracoContentIndexer.IndexPathFieldName, "-1,-21,".MultipleCharacterWildcard());
var result = searchProvider.Search(filter.Compile());
if (result != null)
return result.Select(x => CreateFromCacheValues(ConvertFromSearchResult(x)));
}
catch (Exception ex)
{
if (ex is FileNotFoundException)
{
//Currently examine is throwing FileNotFound exceptions when we have a loadbalanced filestore and a node is published in umbraco
//See this thread: http://examine.cdodeplex.com/discussions/264341
//Catch the exception here for the time being, and just fallback to GetMedia
//TODO: Need to fix examine in LB scenarios!
Current.Logger.Error<PublishedMediaCache>("Could not load data from Examine index for media", ex);
}
else if (ex is AlreadyClosedException)
{
//If the app domain is shutting down and the site is under heavy load the index reader will be closed and it really cannot
//be re-opened since the app domain is shutting down. In this case we have no option but to try to load the data from the db.
Current.Logger.Error<PublishedMediaCache>("Could not load data from Examine index for media, the app domain is most likely in a shutdown state", ex);
}
else throw;
}
}
//something went wrong, fetch from the db
var rootMedia = _mediaService.GetRootMedia();
return rootMedia.Select(m => GetUmbracoMedia(m.Id));

View File

@@ -17,6 +17,11 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
private bool _using;
private bool _registerXmlChange;
// the default enlist priority is 100
// enlist with a lower priority to ensure that anything "default" has a clean xml
private const int EnlistPriority = 60;
private const string EnlistKey = "safeXmlReaderWriter";
private SafeXmlReaderWriter(IDisposable releaser, XmlDocument xml, Action<XmlDocument> refresh, Action<XmlDocument, bool> apply, bool isWriter, bool scoped)
{
_releaser = releaser;
@@ -29,6 +34,12 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
_xml = IsWriter ? Clone(xml) : xml;
}
public static SafeXmlReaderWriter Get(IScopeProvider scopeProvider)
{
var scopeContext = scopeProvider.Context;
return scopeContext?.GetEnlisted<SafeXmlReaderWriter>(EnlistKey);
}
public static SafeXmlReaderWriter Get(IScopeProvider scopeProvider, AsyncLock xmlLock, XmlDocument xml, Action<XmlDocument> refresh, Action<XmlDocument, bool> apply, bool writer)
{
var scopeContext = scopeProvider.Context;
@@ -42,7 +53,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
// get or create an enlisted reader/writer
var rw = scopeContext.Enlist("safeXmlReaderWriter",
var rw = scopeContext.Enlist(EnlistKey,
() => // creator
{
// obtain exclusive access to xml and create reader/writer
@@ -52,7 +63,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
(completed, item) => // action
{
item.DisposeForReal(completed);
});
}, EnlistPriority);
// ensure it's not already in-use - should never happen, just being super safe
if (rw._using)

View File

@@ -38,7 +38,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
/// then passed to all <see cref="PublishedContentCache"/> instances that are created (one per request).</para>
/// <para>This class should *not* be public.</para>
/// </remarks>
class XmlStore : IDisposable
internal class XmlStore : IDisposable
{
private readonly IDocumentRepository _documentRepository;
private readonly IMediaRepository _mediaRepository;
@@ -329,6 +329,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
}
}
// Gets the temp. Xml managed by SafeXmlReaderWrite, if any
public XmlDocument TempXml => SafeXmlReaderWriter.Get(_scopeProvider)?.Xml;
// assumes xml lock
private void SetXmlLocked(XmlDocument xml, bool registerXmlChange)
{