Caching basics

How to cache in memory.

Key takeaways

ICache Interface that defines caching methods.
MemoryCache Cache that stores values in-memory.
NullCache Dummy cache implementation that simulates caching without performing any actual actions.

Introduction

Pip.Services offers several basic components for caching. One of the most important ones is the ICache interface, which must be implemented by all cache components and defines a basic set of methods that all caches must contain. Two other basic components that are worth mentioning are the MemoryCache and NullCache classes. The first stores key-value pairs in-memory, and the second is a dummy cache that can be used to simulate caching. In the following sections, this tutorial explains how to use these components in detail. Other caching tools, such as Redis and Memcached, are explained in separate tutorials.

ICache

This interface contains three important methods for caching, namely, store(), retrieve(), and remove(). As their names indicate, they can be used to store, retrieve, and remove key-value pairs from the cache. Both MemoryCache and NullCache components implement this interface. The following diagram explains their relations:

figure 1

Using a cache component

The two basic cache components offered by the toolkit are the MemoryCache and the NullCache. The first provides the ability to create and manage a cache that stores key-value pairs in memory. The second is a dummy cache implementation that only simulates caching, without producing any actual results.

Pre-requisites

In order to use the MemoryCache component, we need to import it. This can be done with the following import statement:

import { MemoryCache } from "pip-services3-components-nodex";
using PipServices3.Components.Cache;
import (
	cache "github.com/pip-services3-gox/pip-services3-components-gox/cache"
)
import 'package:pip_services3_components/pip_services3_components.dart';
from pip_services4_logic.cache import MemoryCache
Not available

Similarly, for the NullCache:

import { NullCache } from "pip-services3-components-nodex";
using PipServices3.Components.Cache;
import (
	cache "github.com/pip-services3-gox/pip-services3-components-gox/cache"
)
import 'package:pip_services3_components/pip_services3_components.dart';
from pip_services3_components.cache import NullCache
Not available

Create

We can create a memory cache by creating an instance of the cache class. The following code shows how this can be done for the Memory Cache:

let myCache = new MemoryCache();
var myCache = new MemoryCache();
myCache := cache.NewMemoryCache[any]()
var myCache = MemoryCache();
my_cache = MemoryCache()
Not available

And, for the NullCache:

let myCache = new NullCache();
var myCache = new NullCache();
myCache := cache.NewNullCache[any]()
var myCache = NullCache();
my_cache = NullCache()
Not available

Store

We can cache a value by using the store() method. This method accepts four parameters. First, the correlation_id, which is a value that can be used to track executions throughout the call chain. Second, a key that can be used to uniquely identify the stored value. Third, the value to be stored. Lastly, the duration (in milliseconds) for which this value should be kept in the cache. The code below shows how to use this method for both components.

let myCachedValue = await myCache.store(null, "key1", "ABC", 180000);  // Returns "ABC"
var myCachedValue = await myCache.StoreAsync(null, "key1", "ABC", 180000);  // Returns "ABC"
myCachedValue, _ := myCache.Store(context.Background(), "123", "key1", "ABC", 180000) // Returns "ABC"
var myCachedValue = await myCache.store(null, 'key1', 'ABC', 180000); // Returns "ABC"
my_cached_value = my_cache.store(None, "key1", "ABC", 180000)  # Returns "ABC"
Not available

Retrieve

To retrieve a cached value from memory, we can use the retrieve() method, which takes the correlation_id and the cached value’s key as parameters. The code below shows how this method can be used.

let myRetrievedValue = await myCache.retrieve(null, "key1");  // Returns "ABC"
var myRetrievedValue = await myCache.RetrieveAsync<string>(null, "key1");  // Returns "ABC"
myRetrievedValue, _ := myCache.Retrieve(context.Background(), "123", "key1") // Returns "ABC"
var myRetrievedValue = await myCache.retrieve(null, 'key1'); // Returns "ABC"
my_retrieved_value = my_cache.retrieve(None,"key1")   # Returns "ABC"
Not available

Remove

To remove a value from a cache, we can use the remove() method, which takes the correlation_id and the key of the value to be removed as input parameters. The example below shows how to use this method.

await myCache.RemoveAsync(null, "key1");
await myCache.RemoveAsync(null, "key1");
myCache.Remove(context.Background(), "123", "key1")
await myCache.remove(null, 'key1');
my_cache.remove(None, "key1")
Not available

Moreover, if we want to retrieve the removed value:

Not available
Not available
Not available
Not available
my_retrieved_value = my_cache.retrieve(None,"key1")
my_retrieved_value

Not available

We get the following result, which verifies that the key-value pair doesn’t exist any more”

figure 2

Wrapping up

In this tutorial, we have seen how to cache a value for later use. First, we understood the ICache interface. Then, we learned how to use the MemoryCache class, which provides a set of methods to store, retrieve and remove a value from memory. Finally, we saw the NullCache class, which has the same methods as the MemoryCache class, but in practice doesn’t cache any value and only works as a dummy component.