Object Caching vs LinkItemCollection

Vote:
 

Hi all, 

I yesterday stubled on some strange behaviour in a CMS 12 (latest packages) website I'm working on. 

Behaviour:
On a specific page there is a LinkItemCollection property that is used to show some links to other parts of the site.
After a restart the list would not show any links to the visitor, but when I view the page in the CMS in preview mode the links are visible. After a publish the links are visible to the visitor, and after a restart they are gone again.

What I found out so far:

It seems that caching plays a part in this. If I load the page, check if the collection is null and then
invalidate the cache and load the page again the links are there. 

var contentRepo = ServiceLocator.Current.GetInstance<IContentLoader>();
if (page.QuickNavigationLinks == null)
{
    var ccr = ServiceLocator.Current.GetInstance<IContentCacheRemover>();
    ccr.Remove(page.ContentLink);

    var newLoad = contentRepo.Get<SubHomePage>(currentPage.ContentLink);
    if (newLoad.QuickNavigationLinks != null)
    {
        // Now the links are there
    }
}



Then I tried to find out, why an incomplete page was cached. I implemented my own ObjectInstanceCache to intercept the page being cached, and use the callstack to find the origin.

public class MyObjectInstanceCache : IObjectInstanceCache
{
    private readonly IMemoryCache _memoryCache;

    public MyObjectInstanceCache(IMemoryCache memoryCache)
    {
        _memoryCache = memoryCache;
    }

    public void Clear()
    {
        // Do nothing
    }

    public object Get(string key)
    {
        return _memoryCache.Get(key);
    }

    public void Insert(string key, object value, CacheEvictionPolicy evictionPolicy)
    {
        if (key.Equals("EPPageData:62694") && value is SubHomePage page && page.QuickNavigationLinks == null)
        {
            // Here the page is cached without QuickNavigationLinks
            _memoryCache.Set(key, value);   
        }

        _memoryCache.Set(key, value);
    }

    public void Remove(string key)
    {
        _memoryCache.Remove(key);
    }
}


It seems now, that on loading the homepage. The children (including my page) of the homepage are loaded:

var loader = ServiceLocator.Current.GetInstance<IContentLoader>();
return loader.GetChildren<IContent>(parentPage.ContentLink);


And in loading this children I see the page being cached without the QuickNavigationLinks.
Then when I navigate to this page, this page is loaded from cache, and no links are shown.

My questions:

Is this something that makes sence?
Am I missing something here?
Why is the page cached differently when loading is from GetChildren in comparison to the normal Get of the ContentLoader? 

#333297
Nov 22, 2024 11:08
Vote:
 

This puzzled me

  • After a restart the list would not show any links to the visitor, but when I view the page in the CMS in preview mode the links are visible.
  • After a publish the links are visible to the visitor, and after a restart they are gone again.

Some questions.

  1. Did you implement any ResponseCache or OutputCache?
  2. How is VersionCacheSlidingExpiration and ContentCacheSlidingExpiration set up (config in appsettings.json), https://docs.developers.optimizely.com/content-management-system/docs/configuring-cms#contentoptions.

I'd like to know if this issue persist if you disable all caches.

#333412
Edited, Nov 25, 2024 8:28
Vote:
 

We encountered this after updating a bunch of Episerver.* packages. We had to revert the update due to this bug. Below is our git diff:

-        <PackageReference Include="EPiServer.CMS.AspNetCore.HtmlHelpers" Version="12.22.0" />
-        <PackageReference Include="EPiServer.CMS.AspNetCore.Routing" Version="12.22.0" />
-        <PackageReference Include="EPiServer.CMS.AspNetCore.TagHelpers" Version="12.22.0" />
-        <PackageReference Include="EPiServer.CMS.Core" Version="12.22.0" />
-        <PackageReference Include="EPiServer.Framework" Version="12.22.0" />
-        <PackageReference Include="EPiServer.CloudPlatform.Cms" Version="1.6.2" />
-        <PackageReference Include="EPiServer.Find.Cms" Version="16.3.1" />
+        <PackageReference Include="EPiServer.CMS.AspNetCore.HtmlHelpers" Version="12.21.8" />
+        <PackageReference Include="EPiServer.CMS.AspNetCore.Routing" Version="12.21.8" />
+        <PackageReference Include="EPiServer.CMS.AspNetCore.TagHelpers" Version="12.21.8" />
+        <PackageReference Include="EPiServer.CMS.Core" Version="12.21.8" />
+        <PackageReference Include="EPiServer.Framework" Version="12.21.8" />
+        <PackageReference Include="EPiServer.CloudPlatform.Cms" Version="1.6.1" />
+        <PackageReference Include="EPiServer.Find.Cms" Version="16.3.0" />
#333473
Nov 26, 2024 13:07
Magnus Rahl - Dec 02, 2024 8:37
So things worked fine when you had EPiServer.CMS.Core 12.21.8 but broken when you run 12.22.0 (i.e. the commit log above is from the revert)?

We have got another similar report to support. The team will investigate to confirm if this is a bug in the product. If you can confirm the versions that gives us a very narrow range to search for potential causes of a regression (i.e. it would be a regression in 12.22.0).
huseyinerdinc - Dec 02, 2024 8:40
@Magnus Rahl, it is correct. The diff is from the revert. I did not test with any other version but I can confirm that one of the packages above is the reason to the bug.
Magnus Rahl - Dec 02, 2024 8:44
Thanks for the confirmation! We'll investigate ASAP.
Vote:
 

Had some time to test today.

@Eric Herlitz I don't have any ResponseCache or OutputCache implemented, and disabling all caches as suggested helps. (The site is as expected realy slow but the problem does not persist)

@huseyinerdinc I also recently updated my packages, but I'm not entirely sure the problem wasn't there before.
These are the package versions I currently use (so quite similar):

    <PackageReference Include="EPiServer.CloudPlatform.Cms" Version="1.6.1" />
    <PackageReference Include="EPiServer.CMS" Version="12.31.2" />
    <PackageReference Include="EPiServer.CMS.AspNetCore" Version="12.22.0" />
    <PackageReference Include="EPiServer.CMS.AspNetCore.TagHelpers" Version="12.22.0" />
    <PackageReference Include="EPiServer.CMS.AspNetCore.Routing" Version="12.22.0" />
    <PackageReference Include="EPiServer.CMS.UI.AspNetIdentity" Version="12.31.2" />
    <PackageReference Include="EPiServer.Find.Cms" Version="16.3.0" />
    <PackageReference Include="EPiServer.Framework" Version="12.22.0" />

 

#333600
Nov 29, 2024 14:50
Vote:
 

We have confirmed this is a bug and are working to fix it: Bug - CMS-38033

#333790
Dec 03, 2024 11:42
Vote:
 

Also note the workround in the bug description:

"Link collection properties might load data incorrectly when lazy loading is enabled. The error is often intermittent and can be worked around by disabling lazy loading (set ContentOptions.PropertyLazyLoadThreshold = 0)."

#333791
Dec 03, 2024 11:50
Vote:
 

Are there any downsides of setting ContentOptions.PropertyLazyLoadThreshold = 0? Is this what the bugfix will be?

#333890
Dec 05, 2024 7:39
huseyinerdinc - Dec 05, 2024 7:45
We had to do it in a CMS 11 site, it did not affect anything, at least noticeably: https://world.optimizely.com/forum/developer-forum/CMS/Thread-Container/2021/4/are-there-any-drawbacks-of-setting-stringdelayedloadthreshold-to-0/
Magnus Rahl - Dec 05, 2024 7:52
The potential downside is performance. With lazy loading enabled, some property values (default over length of 255 chars I think) will not be loaded from database with the initial load. It will only be loaded and cached in memory if and when that property is accessed the first time.

The bug fix will be fixing the broken lazy loading mechanism for LinkItemCollection. I hope it will be released today or tomorrow.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.