SysGlobalCache versus SysGlobalObjectCache in D365FO

Deep Dive into D365FO Cache: SysGlobalCache versus SysGlobalObjectCache

Have you ever noticed how Dynamics 365 for Finance and Operations (D365FO) initially loads at a snail's pace 🐌 but then speeds up 🚀 when you revisit the same form? That's the magic of caching at work! Caching boosts your application's speed and performance by storing frequently used data in cache memory, letting you skip those time-consuming database calls or complex code runs. 🕒➡️🕐

In this article, we'll take a deep dive into two powerful classes for caching data in D365FO and describe with examples what is the difference between SysGlobalCache and SysGlobalObjectCache. Whether you're wrestling with global variables due to less-than-ideal design patterns 🤔 or striving for peak efficiency 🏆, these cache classes have got you covered. Buckle up and let's get started! 🛠️

When should I use caching in D365FO?

Caching is definitely an abstract concept and it's sometimes hard to imagine where you should use it in D365FO. In real-world scenarios, caching can be used for:

  • Commonly accessed master data like customer, product, and price lists benefit from caching to speed up transaction processing and queries.
  • Session-specific information or so-called session data, such as user preferences or recently viewed items, to improve user experience without frequent database queries.
  • Cache configurations that are fetched frequently but rarely change.
  • Cache common record buffers.
  • Security-related metadata to swiftly verify user roles and permissions during the session.
  • When implementing batch jobs (e.g., Batch Processing) that read the same dataset multiple times, caching can drastically reduce I/O operations against the database.
  • Forms that display summarized or calculated data should use caching to avoid re-calculating the same data repeatedly.
  • Integrations with external systems when calling API can minimize the frequency of requests such as authorization, authentications and others.
  • Commonly used report data or query results to improve the performance of reporting tools and dashboards.
Keep in mind that caching can also bring drawbacks. Only cache what you know is needed because it can impact memory consumption and and cause stale data, code complexity and cache invalidation problems. 😏

How and when to use SysGlobalCache?

The SysGlobalCache class allows you to store and retrieve values from a global in-memory cache, available for the entire client session scope.

Client session scope in D365FO refers to the time between opening a webpage or clicking on a menu item until it is fully loaded. 💡 During this period, the same thread is consistently used in the background. It is important to note that data stored in the client session scope is not accessible in other threads and the data will be cleared automatically once the client session is terminated.

In D365FO you can find the following 3 instances of the SysGlobalCache that can be accessed via:

  • appl variable that references a pre-instantiated object from the Application class,
  • classFactory variable that references object from the ClassFactory class,
  • infolog variable that references object from the Info class.

In the following example, let’s see how to use SysGlobalCache by using appl global variable. To get the global cache variable located on the Application class, use the following code:

The same applies to instances of the ClassFactory and Info classes. There are many places in the standard code where the SysGlobalCache is used, and you can find them with the Find All References option in Visual studio.

You can also create your own instance of the SysGlobalCache class in your code using the constructor static method SysGlobalCache::construct().

Creating your own instance is not recommended because in this case you will need to handle the lifetime of the SysGlobalCache object to be able to share data in your code. The best practice is to use one of the above-mentioned instances (e.g., ClassFactory or Application class).

In the next example, we will show how SysGlobalCache is utilized in Docentric AX Free Edition for the All attachments form. This form displays all D365FO attachments in a grid, allowing a user with appropriate permissions to view, open, edit and download any attachment.

After the user selects a record in the grid, we must verify whether the user has permissions to view or edit the associated attachment details, based on the security context of the DocuView form. To accomplish this, we implement a helper method that takes the selected DocuRef buffer as an input parameter. The helper method code looks like this:

At the start of the method, we first query the global cache to see if it already exists. If it does, we return a container populated with the AllowView and AllowEdit flags. If not, we create a new DocuView form to evaluate the user's permissions for viewing and editing the attachment details. After this evaluation, we cache these permissions in the global cache for faster access in subsequent user sessions.

Utilizing the global cache for storing permissions significantly boosts performance by obviating the need for new DocuView instances. Creating these instances frequently is not resource-efficient, given the overhead associated with each object allocation.

How and when to use SysGlobalObjectCache?

The SysGlobalObjectCache (SGOC) class serves as a kernel-managed caching mechanism, superseding the older SysObjectCache. Introduced in AX2012, SGOC's primary function is to facilitate data sharing across all user sessions in a single process (e.g., single AOS node). In other words, data cached from one user connection becomes accessible to all other users. SGOC operates by storing key-value pairs within a defined "scope".

Both the key and value in SGOC are containers. The key container uniquely identifies the cached object, while the value container holds the object's data.

To access SGOC, you can utilize the global classFactory variable, as the SGOC instance resides on the ClassFactory system class:

Being a singleton class, only one SysGlobalObjectCache instance exists system-wide. However, you can still instantiate a new SGOC object:

If an instance already exists, any new instance will refer to the first original object (i.e., singleton instance). Thus, a value set via one instance is readily available to all other references of SGOC.

In either case, whether using SysGlobalCache or SysGlobalObjectCache, you are responsible for purging outdated key-value pairs from the cache. This is one of the reasons why use of the cache is appropriate only for data that is rarely updated.

The following example show you how to use the SGOC:

Data added to one AOS is accessible to all sessions connected to that specific AOS. However, this data is not automatically distributed to other AOS instances within the same deployment, while all clear cache calls are propagated with a minor delay to all AOS instances and all session. Read more about this behaviour >>
To learn more about SysGlobalObjectCache, check the following Microsoft documentation.

There are multiple areas where the SGOC is used in D365FO, like for Budget cache, Dimension cache, Price cache and so on.

Now let's look at one of the examples how we used SysGlobalObjectCache. We used SGOC in the development of a feature that saves reports to SharePoint with metadata fields. Since metadata insert/update operations occur in isolated sessions separate from the user session, SGOC is essential for relaying accurate error messages to the user should metadata updates fail. The following example is part of DocDocuActionFileWithMetadata used to store document to attachements or print archive.

To retrieve the message from SGOC and display it to the user, we used the following piece of code:

To learn more about Docentric AX feature Saving to SharePoint with Metadata Fields click here.

Troubleshooting and clearing the SysGlobalObjectCache

In rare cases, D365FO may over-cache data, resulting in a failure to refresh the cache. This can create operational issues. To resolve this, one approach is to utilize the SysFlushAOD action menu item. Although this menu item is not directly accessible via any form, it can be invoked through the following URL:

https://[your environment hostname]/?mi=SysClassRunner&cls=SysFlushAOD

This URL triggers the main() method of the SysFlushAOD class. Below is the code snippet from D365FO that executes this action:

Wrapping It Up: To Cache or Not to Cache 🤔

And there you have it, folks! When it comes to juggling data in D365FO, you've got two juggernauts 🤹‍♂️: SysGlobalCache and SysGlobalObjectCache.

Remember, SysGlobalCache is your go-to buddy for session-specific needs. On the flip side, if you're looking to share data across multiple sessions, SysGlobalObjectCache is your cross-session hero.

So before you decide, take a moment to ponder 🤔: "Is this data just for me, or is it a party everyone's invited to?". Your answer will guide you to the right caching mechanism!

Happy coding, cache wizards! 🧙‍♂️💻

Leave a Reply

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

*

Docentric respects your privacy. Learn how your comment data is processed >>

Docentric respects your privacy. Learn how your comment data is processed >>