SaaS CMS has officially launched! Learn more now.

ISynchronizedObjectInstanceCache Load Balancing Issues

Vote:
 

Hi guys, I am using the ISynchronizedObjectInstanceCache for caching items against content in the CMS which has been working great in DEV. We've just moved to a load balanced testing envionment and changes in the CMS to the cached nodes aren't being reflected in the other servers. 

As far as I was aware this cache styem was designed to sync between servers. Does anyone know why this isn't working? Or have any other information in it?

#151872
Aug 09, 2016 13:11
Vote:
 

I've now moved to using the CacheManager instance and it's still not working. Here is my example code, it's build to allow a dictionary of objects cached against a content item.

    public class EpiServerContentCacheManager : ICacheManager
    {
        /// <summary>
        /// Inserts an item in to the cache based upon the content reference.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contentReference">The content reference.</param>
        /// <param name="objectKey">The object key which differentiates different items against an item.</param>
        /// <param name="item">The item.</param>
        public void Insert<T>(ContentReference contentReference, string objectKey, T item) where T : class, ICacheableItem
        {
            var dictionary = GetCacheDictionary(contentReference);

            if (dictionary != null)
            {
                var existingItem = dictionary[objectKey];

                if (existingItem == null)
                {
                    dictionary.Add(objectKey, item);
                }
                else
                {
                    dictionary[objectKey] = item;
                }
            }
            else
            {
                dictionary = new Dictionary<string, object> {{objectKey, item}};
            }

            Insert(contentReference, dictionary);
        }

        /// <summary>
        /// Gets an item from the cache based upon it's content reference.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="contentReference">The content reference.</param>
        /// <param name="objectKey">The object key which differentiates different items against an item.</param>
        /// <returns>T.</returns>
        public T Get<T>(ContentReference contentReference, string objectKey) where T : class, ICacheableItem
        {
            var dictionary = GetCacheDictionary(contentReference);

            if (dictionary != null && dictionary.ContainsKey(objectKey))
            {
                return (T) dictionary[objectKey];
            }

            return null;
        }

        /// <summary>
        /// Removes the specified content reference.
        /// </summary>
        /// <param name="contentReference">The content reference.</param>
        public void Remove(ContentReference contentReference)
        {
            var key = GetCacheKey(contentReference);
            CacheManager.Remove(key);
        }

        /// <summary>
        /// Gets the cache key.
        /// </summary>
        /// <param name="contentReference">The content reference.</param>
        /// <returns>System.String.</returns>
        private string GetCacheKey(ContentReference contentReference)
        {
            return $"ContentDependency:{contentReference.ID}";
        }

        private Dictionary<string, object> GetCacheDictionary(ContentReference contentReference)
        {
            var key = GetCacheKey(contentReference);
            return (Dictionary<string, object>)CacheManager.Get(key);
        }

        /// <summary>
        /// Inserts the specified content reference.
        /// </summary>
        /// <param name="contentReference">The content reference.</param>
        /// <param name="dictionary">The dictionary.</param>
        private void Insert(ContentReference contentReference, Dictionary<string, object> dictionary)
        {
            var key = GetCacheKey(contentReference);
            CacheManager.Insert(
                    key,
                    dictionary,
                    new CacheEvictionPolicy(
                        new List<string> { DataFactoryCache.PageCommonCacheKey(contentReference) }
                    )
                );
        }
    }
#151875
Aug 09, 2016 14:12
Vote:
 
#151879
Aug 09, 2016 15:37
Vote:
 

It's only the CacheManager/ISynchronizedObjectInstanceCache that isn't working, all the standard eventing and load balancing is working with content that isn't being cached through these mechanisms. 

#151885
Aug 09, 2016 16:35
Vote:
 

Just to clarify, what exactly isn't working? "Syncing" is kinda broad description of what the event system is doing. What it does is to invalidate the cache. So if you add stuff to the cache, it's not added to all nodes automatically.

#151887
Aug 09, 2016 16:39
Vote:
 

As far as I am aware from examples around and the code comments the use of the CacheManager when adding in objects that have a cache eviction policy based upon a ContentReference should store the object in memory as long as the IContent item of that ContentReference hasn't changed. If the item does change the object would be evicted from the cache accross all load balanced servers which should be the next time the item is requested it will be re-inserted in to the cache.

#151888
Aug 09, 2016 16:55
Vote:
 

Then we're on the same page :)

Are you sure this is related to load balancing? Is the item evicted from the server where the item was changed?

#151889
Aug 09, 2016 17:07
Vote:
 

Yes, For our QA process we have a CMS and a WEB box that the code is deployed to. If I change the content that this is all linked to (which is a container page used for some configuration data) I see the item appearing on the front end of the CMS box but the content is not being updated on the WEB box. As I've said non cached items items are showing up so the Events system is definately working (also this using a base build that's not changed events wise and has been working on multiple projects).

#151890
Aug 09, 2016 17:12
Vote:
 

Thanks for your help on this, it turns out the changes I made to use CacheManager as shown above are working. We've recently had some changes to out TeamCity setup to use GitVersion for semantic versioning which has caused a problem with Octopus. Long story short the deployment had redeployed the non updated code. Typical, thanks for the help.

#151891
Aug 09, 2016 17:36
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* 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.