Skip to content

Commit

Permalink
Merge pull request #1636 from umbraco/temp-U4-9222
Browse files Browse the repository at this point in the history
U4-9222 The in memory XML cache is cloned everytime there is a content save even if there is nothing published
  • Loading branch information
zpqrtbnk authored Nov 28, 2016
2 parents 1221c0e + 309081c commit 8305a1a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 43 deletions.
42 changes: 24 additions & 18 deletions src/Umbraco.Web/umbraco.presentation/content.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ private content()
var profingLogger = new ProfilingLogger(
logger,
ProfilerResolver.HasCurrent ? ProfilerResolver.Current.Profiler : new LogProfiler(logger));

// prepare the persister task
// there's always be one task keeping a ref to the runner
// so it's safe to just create it as a local var here
Expand All @@ -71,7 +71,7 @@ private content()
// once released, the cache still works but does not write to file anymore,
// which is OK with database server messenger but will cause data loss with
// another messenger...

runner.Shutdown(false, true); // wait until flushed
_released = true;
});
Expand Down Expand Up @@ -145,7 +145,7 @@ public string UmbracoXmlDiskCacheFileName
}

//NOTE: We CANNOT use this for a double check lock because it is a property, not a field and to do double
// check locking in c# you MUST have a volatile field. Even thoug this wraps a volatile field it will still
// check locking in c# you MUST have a volatile field. Even thoug this wraps a volatile field it will still
// not work as expected for a double check lock because properties are treated differently in the clr.
public virtual bool isInitializing
{
Expand Down Expand Up @@ -327,11 +327,17 @@ internal virtual void UpdateSortOrder(IContent c)
// this updates the published cache to take care of the situation
// without ContentService having to ... what exactly?

// no need to do it if the content is published without unpublished changes,
// though, because in that case the XML will get re-generated with the
// correct sort order.
if (c.Published)
return;
// no need to do it if
// - the content is published without unpublished changes (XML will be re-gen anyways)
// - the content has no published version (not in XML)
// - the sort order has not changed
// note that
// - if it is a new entity is has not published version
// - if Published is dirty and false it's getting unpublished and has no published version
//
if (c.Published) return;
if (c.HasPublishedVersion == false) return;
if (c.WasPropertyDirty("SortOrder") == false) return;

using (var safeXml = GetSafeXmlWriter(false))
{
Expand Down Expand Up @@ -419,7 +425,7 @@ internal void ClearDocumentCache(Document doc)
{
XmlNode x;

// remove from xml db cache
// remove from xml db cache
doc.XmlRemoveFromDB();

// clear xml cache
Expand All @@ -435,7 +441,7 @@ internal void ClearDocumentCache(Document doc)
{
var prov = (UmbracoSiteMapProvider)SiteMap.Provider;
prov.RemoveNode(doc.Id);
}
}
}
}

Expand Down Expand Up @@ -486,7 +492,7 @@ private void ClearContextCache()
if (UmbracoContext.Current != null && UmbracoContext.Current.HttpContext != null && UmbracoContext.Current.HttpContext.Items.Contains(XmlContextContentItemKey))
UmbracoContext.Current.HttpContext.Items.Remove(XmlContextContentItemKey);
}

/// <summary>
/// Load content from database
/// </summary>
Expand Down Expand Up @@ -517,7 +523,7 @@ private XmlDocument LoadContentFromDatabase()
public void PersistXmlToFile()
{
}

internal DateTime GetCacheFileUpdateTime()
{
//TODO: Should there be a try/catch here in case the file is being written to while this is trying to be executed?
Expand Down Expand Up @@ -566,7 +572,7 @@ private static bool XmlIsImmutable
private static bool UseLegacySchema
{
get { return UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema; }
}
}

#endregion

Expand Down Expand Up @@ -770,9 +776,9 @@ public void Dispose()
_releaser.Dispose();
_releaser = null;
}

}

private static string ChildNodesXPath
{
get
Expand Down Expand Up @@ -866,9 +872,9 @@ private void SaveXmlToStream(XmlDocument xml, Stream writeStream)
// and in addition, writing async is never fully async because
// althouth the writer is async, xml.WriteTo() will not async

// that one almost works but... "The elements are indented as long as the element
// that one almost works but... "The elements are indented as long as the element
// does not contain mixed content. Once the WriteString or WriteWhitespace method
// is called to write out a mixed element content, the XmlWriter stops indenting.
// is called to write out a mixed element content, the XmlWriter stops indenting.
// The indenting resumes once the mixed content element is closed." - says MSDN
// about XmlWriterSettings.Indent

Expand Down Expand Up @@ -1073,7 +1079,7 @@ private static void TransferValuesFromDocumentXmlToPublishedXml(XmlNode document
//TODO: This could be faster, might as well just iterate all children and filter
// instead of selecting matching children (i.e. iterating all) and then iterating the
// filtered items to remove, this also allocates more memory to store the list of children.
// Below we also then do another filtering of child nodes, if we just iterate all children we
// Below we also then do another filtering of child nodes, if we just iterate all children we
// can perform both functions more efficiently
var dataNodes = publishedNode.SelectNodes(DataNodesXPath);
if (dataNodes == null) throw new Exception("oops");
Expand Down
34 changes: 15 additions & 19 deletions src/umbraco.cms/businesslogic/CMSNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1142,25 +1142,24 @@ protected void UpdateTempPathForTree(string Path)

protected virtual XmlNode GetPreviewXml(XmlDocument xd, Guid version)
{
var xmlDoc = new XmlDocument();

XmlDocument xmlDoc = new XmlDocument();
using (var sqlHelper = Application.SqlHelper)
using (XmlReader xmlRdr = sqlHelper.ExecuteXmlReader(
"select xml from cmsPreviewXml where nodeID = @nodeId and versionId = @versionId",
sqlHelper.CreateParameter("@nodeId", Id),
sqlHelper.CreateParameter("@versionId", version)))
{
xmlDoc.Load(xmlRdr);
}
var xmlStr = ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar<string>(
"select xml from cmsPreviewXml where nodeID = @nodeId and versionId = @versionId",
new { nodeId = Id, versionId = version });

if (xmlStr.IsNullOrWhiteSpace()) return null;

xmlDoc.LoadXml(xmlStr);

return xd.ImportNode(xmlDoc.FirstChild, true);
}

protected internal virtual bool PreviewExists(Guid versionId)
{
using (var sqlHelper = Application.SqlHelper)
return sqlHelper.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId=@nodeId and versionId = @versionId",
sqlHelper.CreateParameter("@nodeId", Id), sqlHelper.CreateParameter("@versionId", versionId)) != 0;
return ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar<int>(
"SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId=@nodeId and versionId = @versionId",
new {nodeId = Id, versionId = versionId}) != 0;

}

Expand All @@ -1172,15 +1171,12 @@ protected internal virtual bool PreviewExists(Guid versionId)
[MethodImpl(MethodImplOptions.Synchronized)]
protected void SavePreviewXml(XmlNode x, Guid versionId)
{
var sql = PreviewExists(versionId) ? "UPDATE cmsPreviewXml SET xml = @xml, timestamp = @timestamp WHERE nodeId=@nodeId AND versionId = @versionId"
string sql = PreviewExists(versionId) ? "UPDATE cmsPreviewXml SET xml = @xml, timestamp = @timestamp WHERE nodeId=@nodeId AND versionId = @versionId"
: "INSERT INTO cmsPreviewXml(nodeId, versionId, timestamp, xml) VALUES (@nodeId, @versionId, @timestamp, @xml)";

using (var sqlHelper = Application.SqlHelper)
sqlHelper.ExecuteNonQuery(sql,
sqlHelper.CreateParameter("@nodeId", Id),
sqlHelper.CreateParameter("@versionId", versionId),
sqlHelper.CreateParameter("@timestamp", DateTime.Now),
sqlHelper.CreateParameter("@xml", x.OuterXml));
ApplicationContext.Current.DatabaseContext.Database.Execute(
sql, new {nodeId = Id, versionId = versionId, timestamp = DateTime.Now, xml = x.OuterXml});

}

protected void PopulateCMSNodeFromReader(IRecordsReader dr)
Expand Down
13 changes: 7 additions & 6 deletions src/umbraco.cms/businesslogic/web/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1560,12 +1560,13 @@ private void saveXml(XmlNode x)
private XmlNode importXml()
{
XmlDocument xmlDoc = new XmlDocument();
using (var sqlHelper = Application.SqlHelper)
{
using(var xmlRdr = sqlHelper.ExecuteXmlReader(string.Format(
"select xml from cmsContentXml where nodeID = {0}", Id)))
xmlDoc.Load(xmlRdr);
}

var xmlStr = ApplicationContext.Current.DatabaseContext.Database.ExecuteScalar<string>(
"select xml from cmsContentXml where nodeID = @nodeId", new {nodeId = Id});

if (xmlStr.IsNullOrWhiteSpace()) return null;

xmlDoc.LoadXml(xmlStr);

return xmlDoc.FirstChild;
}
Expand Down

0 comments on commit 8305a1a

Please sign in to comment.