ecLearn - Learning Management System built on top of Microsoft Dataverse for Power Platform and Dynamics 365 users

ENGINEERED CODE BLOG

Automatic Cache Invalidation for xRM Portals Community Edition

In a January blog post on upgrading to the xRM Portals Community Edition, I promised to look into automatic cache invalidation. It only took a few months, but I’m finally delivering on that promise.

Why We Both Love and Hate Caching

I don’t think anyone has ever accused a website built with Dynamics 365 Portals (or its predecessor, Adxstudio Portals) of being the fastest in the world. Anyone who has worked with it knows that the first time it loads, it can a while (sometimes minutes). But after the first load, things get quite a bit better – this is thanks to the magic of caching.

The vast majority of the data that you see on a Portal comes directly from a Dynamics 365 instance. When you load a site for the first time, there are a lot of requests that need to happen in order to display the page. The site map needs to be built, all of the data for web links that drive menus need to be requested, the content of the page itself, etc. To avoid this slowness all of the time, the Portal code relies on caching – that is, it remembers the response to requests so that it doesn’t need to ask again if the code needs the same information. So, for example, once the requests to build the main navigation have been done once, they don’t need to be done for other pages.

This all works great as long as the data in Dynamics 365 doesn’t change. In order to avoid a stale cache (that is, the Portal displaying old data that has since changed), there needs to be a mechanism to notify that Portal that certain data has changed. We call this cache invalidation.

It’s important to note that if the data is being changed via the Portal itself (for example, via front-side editing), there is no need to invalidate the cache. Since you’re making the change through the Portal, the Portal knows that particular data has changed.

In the next few sections, I’ll look into how this cache invalidation worked in the different versions of Portals.

How It Worked in Version 7

The technique used in the days of Adxstudio Portals Version 7 was using Dynamics 365 Plugins that ran on certain change events to send notifications to the Portal. You needed to setup the “Web Notification URL” entity to tell the plugin where your Portal was located, and then these notifications would send a message via HTTP that includes what type of change it was, and for which entity. Based on this information, the Portal would invalidate the parts of its cache that are impacted by that change in data.

In earlier releases of version 7, these plugins were registered on almost all Dynamics 365 events (create, change, delete of pretty much any entity). While this made sure that the Portal was very up-to-date, this led to performance issues. Imagine importing 10,000 contacts, and each one of these contacts causing a plugin to fire that needed to send a notification to the Portal. This was a heavy load on both Dynamics 365, and the Portal itself.

This was addressed in one of the later releases of version 7; they introduced the ability to restrict the notifications to certain entities.

As a bonus for developers, there was also a quick and easy way to clear the entire cache for a website. Adxstudio provided a bit of JavaScript that could be included in a bookmark that would call the service on the Portal responsible for clearing the cache. This was useful because the plugin technique didn’t often work in development, since that technique requires that the Portal be accessible to the Dynamics 365 server. During development it is very common that the Portal would be running on a local development machine that was not exposed to the Dynamics 365 instance.

How It Works in Version 8

The Microsoft version moves away from the plugin model; instead, they use Azure Event Hub to propagate messages from Dynamics 365 to the Portal to make it aware of changes to Dynamics 365 data. When first released, this was a pretty major pain point for most customers – this technique wasn’t nearly as reliable as the previous one, and they removed the ability to clear the cache of the website using the JavaScript in the bookmark. It seemed like half the time it didn’t work, forcing us to have to reboot the server to clear the cache (this was also before the days of the button on /_services/about to clear the cache). As described above, the first page load after clearing all of the cache can take a while, so any type of debugging was painful since most changes required a server reboot.

Thankfully, those issues seem to be mostly resolved. In our experience, the vast majority of the time when a change happens in Dynamics 365 the Portal is updates pretty quickly. And if they don’t, we at least have the clear cache button to avoid doing a full server reboot.

How It Works in xRM Portals Community Edition

Since xRM Portals Community Edition is based on Version 8 of Portals, my guess is that in theory, you could probably setup the event hub invalidation like Microsoft has done for their offering. However, I didn’t try this.

Instead, I’m happy to report that the old technique (using plugins) still works, albeit with a bit of configuration if you’re upgrading from version 7.

The big change is the location of the service that handle the cache invalidation. In v7, it was located at /Cache.axd; in xRM Portals Community Edition, it’s located at /WebNotification.axd.

With that one difference in mind, the rest is pretty much the same, and so the documentation available here applies. The “WebNotification” solution allows you to choose the entities you want to send notifications for.

If you are upgrading from version 7 and you had already configured Web Notifications, I recommend the following steps (after you’ve upgraded all of the solutions and removed the Adxstudio solutions) to ensure your configuration is properly updated:

  1. Note the URL of any existing Web Notification URLs.
  2. Delete any existing Web Notification URL entities.
  3. Create new Web Notification URL entities for each one you deleted in the previous step, but replace /Cache.axd with /WebNotification.axd. Important: you can’t just update your existing entries, as there is a token that needs to be created, and this is done via a plugin on the Create event of Web Notification URLs.
  4. Open the “WebNotifications” solution and browse to the “Configuration” area. Click the “Enable Notifications” button. If notifications are already enabled, disable and re-enable them. This is important to force the plugin configuration to get the new Web Notification URL.

The browser shortcut to kill the cache that is useful during development will not work, even if you update the JavaScript to point to the new WebNotification.axd handler. The handler is now more sophisticated/secure, and requires authentication via a token for it to work, which is not easily done via browser shortcut. My recommendation is to continue to use the “Clear Cache” button available on the _/services/about/ page during development.

8 responses to “Automatic Cache Invalidation for xRM Portals Community Edition”

  1. […] check out my blog post on cache invalidation for xRM Portals Community Edition […]

  2. Jason McNeil says:

    Great timing, your tip about deleting the old Web Notification Entities just saved my bacon, out of curiosity, where does it store this new token that is created when creating the Web Notification Entity record?

  3. Nicholas Hayduk says:

    Hey Jason ,

    Glad to hear this post was helpful!

    The token is stored on the Web Notification URL entity itself. There is a new field on the entity (I think it’s called adx_token if my memory serve me right), and a plugin that sets the field on the create of those records.

    The CRM passes that token as part of the Web Notification request to the Portal, and the Portal validates that the token is correct before actually invalidating the cache. It’s essentially a password so that not just anyone can send Web Notification requests to the Portal.

    Nick

  4. Spero says:

    The approach you’ve outlined is not recommended…

    **Microsoft Dynamics 365 Portal Add-on’s Do Not Require this Configuration**
    Attempting to Configure Web Notifications for your Microsoft Dynamics 365 Portal Add-on will result in plug-in failure, system job backlog, and is counterproductive to the desired outcome of enabling Web Notifications.

    https://community.adxstudio.com/products/adxstudio-portals/documentation/developers-guide/cache/web-notifications/

    • Nicholas Hayduk says:

      Hi Spero,

      My post is directed at the xRM Portals Community Edition (so if you’re building a solution based on the source code release provided by Microsoft). The comment on the page you linked to is directed at users of the Microsoft SaaS Portals offering, which uses Azure Event Hub to notify the website for cache invalidation, so it doesn’t require the web notifications technique.

      It was actually Microsoft that notified me that the Web Notification technique was still available with the source code release, so as far as I know, it’s not not recommended.

      Nick

  5. Hany says:

    Hello,

    Great post that explains the changes nicely. Having followed through with the changes we are still seeing incorrect behaviour. The URL https:<<portal url??/_services/about just displays Portal 0.0.0.0

    There is no disable cache button. I suspect our solutions are out of date. Do you think that is the case?

    Thanks,
    Hany

    • Nicholas Hayduk says:

      Hi Hany,

      For the Portal Source Code Release/xRM Portals Community Edition, you’ll always see the version number of 0.0.0.0 – that is expected. If that’s all you see on the page, that means you’re not logged in as an administrator. Log in as someone that has the Administrators Web Role, and you should see the additional functionality, including the clear cache button.

      Nick

  6. Thanks for this trick to solve the issue!!. We were looking for the outdated version of the ADX guide, that pointed the url to cache.axd instead of webnotifications.axd.

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact

Engineered Code is a web application development firm and Microsoft Partner specializing in web portals backed by Dynamics 365 & Power Platform. Led by a professional engineer, our team of technology experts are based in Regina, Saskatchewan, Canada.