Search code examples
sitecoresitecore8

Sitecore item deserialization is slow / triggering cache-clear


Problem: when using the Sitecore.Data.Serialization.Managerto de-serialize serialized items into Sitecore 8, my caches get cleared. This shouldn't be so, since I call it with option DisableEvents = true like this:

var options = new Sitecore.Data.Serialization.LoadOptions(masterDb);
options.ForceUpdate = true;
options.DisableEvents = true;

using (new Sitecore.SecurityModel.SecurityDisabler())
{
    Sitecore.Data.Serialization.Manager.LoadItem(itemPath, options);
}

Still, though, cache is being cleared - with debugging enabled, I get this:

36956 19:32:31 INFO Loading item from path /master/sitecore/templates/SomeFolder/SomeItem.item.

36956 19:32:34 WARN All caches have been cleared. This can decrease performance considerably.

36956 19:32:34 DEBUG All caches have been cleared. Stack trace: at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace() at Sitecore.Caching.CacheManager.ClearAllCaches() at Sitecore.Data.Serialization.Manager.<.cctor>b__1(SerializationFinishedEvent event) at Sitecore.Eventing.EventProvider.RaiseEvent(Object event, Type eventType, EventContext context) at Sitecore.Data.Serialization.Manager.DeserializationFinished(String databaseName)


Solution

  • EDIT/UPDATE

    Marek's answer made me realize, I was saying something wrong. I will leave my original proposed answer intact to not cause confusion. But to sum up, calling the LoadItemmethod with option DisableEventsworks as expected. Only does it - to make up for the lack of appropriate events getting fired - trigger Manager.DeserializationFinished(...) which in turn (at least per my default Sitecore 8 setup) calls CacheManager.ClearAllCaches().

    My wrong conclusion was triggered by the fact, that the CacheManager.ClearAllCaches()method is called using Sitecore's own * EventProvider* - so, as Marek points out - this is an unfortunate coincidence / clash of naming.

    Actually, triggering CacheManager.ClearAllCaches() is what I wanted to avoid. So I guess somehow this "workaround" makes my deserialization faster (because it doesn't clear all the caches for each execution).


    ORIGINAL POST

    Ok, so I went to town and eventually discovered this, disassembling Sitecore.Data.Serialization.Manager.LoadItem(...)method (note: this is Sitecore core stuff (with my comments)):

    public static Item LoadItem(string path, LoadOptions options)
        {
          Assert.ArgumentNotNullOrEmpty(path, "path");
          Assert.ArgumentNotNull((object) options, "options");
          if (!options.DisableEvents) <-------------------------- HERE IS THE BUG
            return Manager.DoLoadItem(path, options);
          Item obj;
          using (new EventDisabler())
            obj = Manager.DoLoadItem(path, options);
          //This next line fires the events - but to get here, DisableEvents must be true.
          Manager.DeserializationFinished(Manager.GetTargetDatabase(path, options));
          return obj;
        }
    

    This looks like a bug. "If not options.DisableEvents return". There's one too many "not"?

    The workaround is simply to set

    options.DisableEvents = false;
    

    Setting it to falsedisables the events listening at SerializationFinishedEvent, in this case a handler, that triggers Sitecore.Caching.CacheManager.ClearAllCaches() as hinted by the stack-trace. Even though it seems like it should be the other way around.