The hidden gotcha with IObjectInstanceCache

It’s not a secret that cache is one of the most, if not the most, important factors to their website performance. Yes cache is great, and if you are using Optimizely Content/Commerce Cloud, you should be using ISynchronizedObjectInstanceCache to cache your objects whenever possible.

But caching is not easy. Or rather, the cache invalidation is not easy.

To ensure that you have effective caching strategy, it’s important that you have cache dependencies, i.e. In principles, there are two types of dependencies:

  • Master keys. This is to control a entire cache “segment”. For example, you could have one master key for the prices. If you needs to invalidate the entire price cache, just remove the master key and you’re done.
  • Dependency keys. This is to tell cache system that your cache item depends on this or that object. If this or that object is invalidated, your cache item will be invalidated automatically. This is particularly useful if you do not control this or that object.

ISynchronizedObjectInstanceCache allows you to control the cache dependencies by CacheEvictionPolicy . There are a few ways to construct an instance of CacheEvictionPolicy, from if the cache expiration will be absolute (i.e. it will be invalidated after a fixed amount of time), or sliding (i.e. if it is accessed, its expiration will be renewed), to if your cache will be dependent on one or more master keys, and/or one or more dependency keys, like this

   
        /// <summary>
        /// Initializes a new instance of the <see cref="CacheEvictionPolicy"/> class.
        /// </summary>
        /// <param name="cacheKeys">The dependencies to other cached items, idetified by their keys.</param>
        public CacheEvictionPolicy(IEnumerable<string> cacheKeys)

        /// <summary>
        /// Initializes a new instance of the <see cref="CacheEvictionPolicy"/> class.
        /// </summary>
        /// <param name="cacheKeys">The dependencies to other cached items, idetified by their keys.</param>
        /// <param name="masterKeys">The master keys that we depend upon.</param>
        public CacheEvictionPolicy(IEnumerable<string> cacheKeys, IEnumerable<string> masterKeys)

The constructors that takes master keys and dependency keys look pretty the same, but there is an important difference/caveat here: if there is no dependency key already existing in cache, the cache item you are inserting will be invalidated (i.e. removed from cache) immediately. (For master keys, the framework will automatically add an empty object (if none existed) for you.)

That will be some unpleasant surprise – everything seems to be working fine, no error whatsoever. But, if you look closely, your code seems to be hitting database more than it should. But other than that, your website performance is silently suffering (sometimes, not “silently”)

This is an easy mistake to make – I did once myself (albeit long ago) in an important catalog content cache path. And I saw some very experienced developers made the same mistake as well (At this point you might wonder if the API itself is to blame)

Take away:

  • Make sure you are using the right constructor when you construct an instance of CacheEvictionPolicy . Are you sure that the cache keys you are going to depend on, actually exist?

In newer version of CMS, there would be a warning in log if the cache is invalidated immediately, however, it could be missed, unless you are actively looking for it.

Note that this behavior is the same with ISynchronizedObjectInstanceCache as it extends IObjectInstanceCache.

Delete the undelete-able folder – Windows 7, 8, 10

If you are using Windows 7, 8, or 10, sometime there are some folders appear to be super stubborn, and refuse to go away. No matter how much you try, it just can’t be deleted. It’s undelete-able. Any attempts would result in this dreadful dialog box:

“Are you f*cking kidding me? This is my computer and I have the the absolute control over everything” – You said. Naturally, you would go to open the Security tab in Properties dialog to grant the permissions to everyone.

Strangely, the tab is empty! In other words, there is no one granted permission to nothing.

What? Why? How?




The truth is quite shocking: the folder might be already deleted – but there are processes still referring to it – and by that they keep the handle to the folder open. When that happens, you can’t really do anything to the folder without terminating the process first.

How to find the process then?

Just use Process Explorer, a free SysInternals tool from Microsoft.  Download, extract and run the .exe file (procexp.exe if you are running x86 version, or procexp64.exe if you are running 64 bit version of Windows) Click on Find/Find Handle or Dll, or use Ctrl+F shortcut. In this case we’re looking for typings, which is a fairly unique string. You can of course search by the path if the folder name is quite generic (i.e. there might be a lot of them). Wait for a little bit for this to show up. We got you the sneaky process(es):

Now you know which process is holding the handle to the folder, it’s as easy to fix it. Double click on the process and Process Explorer even let you know the parent process. In most of the cases you can have a peaceful exit and everything will be fixed. In worst cases, a forceful close might be needed.

 

Debuging React tests with Visual Studio Code

Visual Studio Code is awesome and it is getting more and more popular in front end development. It’s great to write code, but you know what, it can be an IDE and allow you to debug your tests as well:

Go to Debug/Add Configuration menu and add this setting:

{
	"version": "0.2.0",
	"configurations": [
		{
		  "name": "Debug JS Tests",
		  "type": "node",
		  "request": "launch",
		  "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/react-scripts-ts",
		  "args": [
			  "test",
			 "--runInBand",
			 "--no-cache",
			 "--env=jsdom"
		  ],
		  "cwd": "${workspaceRoot}",
		  "protocol": "inspector",
		  "console": "integratedTerminal",
		  "internalConsoleOptions": "neverOpen"
		}
	]
}

You can see that we are invoke the react-scripts-ts command with test argument. This also means we are not limited to tests – but I’m yet to debug the normal code.




Now it’s important to remember: you have to open your root folder, in most of the cases, the parent folder of src, in Visual Studio Code. This is to make sure Visual Studio can access the node_modules folder, as well as it can access package.json if needed. I tried to open src folder and a bunch of errors were thrown to my face.

Now you can happily debug your React tests with VS Code:

 

Multiple catalogs with same url

This is an excerpt from my second book . The first chapter is available to read for free.

A business is having an Episerver Commerce instance with multiple sites and multiple catalogs set up. They want to make sure each site will use one catalog, and all of them will share the same url for catalog structure. So it’ll be “https://site-a.com/products/category/”, and “https://site-b.com/products/category/”. Site A and site B are using different catalogs.

Is this doable? Yes! It’s just a matter of magic with the routing. This time, we would need to do an implementation of HierarchicalCatalogPartialRouter ourselves. First, let’s create a template for it:

    
public class MultipleSiteCatalogPartialRouter : HierarchicalCatalogPartialRouter
    {
        private readonly IContentLoader _contentLoader;

        public MultipleSiteCatalogPartialRouter(Func routeStartingPoint, CatalogContentBase commerceRoot, bool enableOutgoingSeoUri, IContentLoader contentLoader) 
            : base(routeStartingPoint, commerceRoot, enableOutgoingSeoUri)
        {
            _contentLoader = contentLoader;
        }
    }

Continue reading “Multiple catalogs with same url”

Fixing HTTP Error 500.19 – Internal Server Error

When you are trying to setup an IIS website on your local machine/new server, it’s very likely that you are going to get this error

HTTP Error 500.19 – Internal Server Error

The requested page cannot be accessed because the related configuration data for the page is invalid.

Detailed Error Information:

Module   IIS Web Core
Notification   Unknown
Handler   Not yet determined
Error Code   0x8007000d
Config Error
Config File   \\?\C:\EL\EL\CMS\web.config
Requested URL   http://el:80/
Physical Path
Logon Method   Not yet determined
Logon User   Not yet determined

Config Source:

   -1: 
    0: 

More Information:

This error occurs when there is a problem reading the configuration file for the Web server or Web application. In some cases, the event logs may contain more information about what caused this error.View more information »

IIS could have had a better message of what is wrong, but we will have to live with this right now. Here’s the check lists you can go through:

Missing IIS features

Your IIS installation might be missing some critical features that are required to run the website (in this case, to parse the web.config). Make sure your IIS instance has all these features installed:

Missing IIS UrlRewrite module

The website might have URL Rewrite rules and your IIS does not have that installed. Simply go here https://www.iis.net/downloads/microsoft/url-rewrite, download and install it.

Speed up your Catalog incremental indexing

As your products are being constantly updated, you would naturally want them to be properly (and timely) indexed – as that’s crucial to have the search results that would influence your customers into buying stuffs. For example, if you just drop the prices of your products , you would want those products to appear in new price segment as soon as possible.

This should be very easy with Find.Commerce – so if you are using Find (which you should) – stop reading, nothing for you here. Things, however, can be more complicated if you are using the more “traditional” SearchProvider.

Continue reading “Speed up your Catalog incremental indexing”

Fixing Cannot find module ‘sync-exec’ error with yarn install

Error message:
clientResources\node_modules\uglifyjs-webpack-plugin: Command failed. Cannot find module ‘sync-exec’
Reason:
uglifyjs-webpack-plugin 0.4.6 defines this command 
“postinstall”: “node lib/post_install.js”
which looks like this
var execSync = require('child_process').execSync;
var fs = require('fs');

// Node 0.10 check
if (!execSync) {
execSync = require('sync-exec');
}

So if your node instance is older than 0.10, it will fallback to require sync-exec . Unlike execSync which is a builtin module, sync-exec is, or was an old module that you have to install explicitly. If your node instance does not have that installed, boom!

Continue reading “Fixing Cannot find module ‘sync-exec’ error with yarn install”

Why you should upgrade to the latest version

I made no secret that I’m a die-hard advocate for upgrading to latest EPiServer CMS/Commerce version. There are several reasons for that, mostly from new shiny features that your businesses dearly need, new big performance improvements that your customers firmly demand.

But there is another, not so obvious reason: support.

Let me tell you a story.

This morning we received a support case from support team. A customer recently upgraded from Commerce 7.5 (Eww) to 11.7 (Yay!), things went well except they had a small problem with data displaying in Catalog UI. Some of the properties were not properly displayed, but they are still showing correct in Commerce Manager.

Continue reading “Why you should upgrade to the latest version”

ServiceAPI + Postman, a match in heaven

No, it’s just a note-to-self.

A lot of customers have been using ServiceAPI, and to great successes. We also have very good documentation here – of which largely thanks to my colleague Mark Hall. But what if you want to play around with ServiceAPI and don’t want to write app/build/run it yourself? The answer is simple: There are many REST Clients can do the job for you, and Postman is usually regarded as the best/most popular one.

But, the documentation are for C# client, it can be quite confusing to use Postman to work with ServiceAPI for the first time (or times). If you are experienced with Postman, great! But if you are not – like me – when you use Postman from time to time and everytime it’s new, then this post can be useful to you. Today I need to do some tests with ServiceAPI, and I had to spend some time figuring out how to use Postman – so I decided it’s better to have all of those noted for future reference.

Continue reading “ServiceAPI + Postman, a match in heaven”

Choose your battles

This is the third part of the series: How to survive and thrive – a series for new developers to become better at their jobs. You can read the first two parts here and here.

In military, there is a term of “uphill battle”. That when you have to fight your way up a hill, when you enemy controls the top. It’s a very difficult fight and your chance of success is low. Any experienced military leader knows uphill battles are something you should avoid until there are no other options.

That also applies with any jobs. Including programming.

The truth is, you shouldn’t fight the battles you can’t win.
Continue reading “Choose your battles”