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-services4-logic-node';
Not available
import (
	cache "github.com/pip-services4/pip-services4-go/pip-services4-logic-go/cache"
)
Not available
from pip_services4_logic.cache import MemoryCache
Not available

Similarly, for the NullCache:

import { NullCache } from 'pip-services4-logic-node';
Not available
import (
	cache "github.com/pip-services4/pip-services4-go/pip-services4-logic-go/cache"
)
Not available
from pip_services4_logic.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();
Not available
myCache := cache.NewMemoryCache[any]()
Not available
my_cache = MemoryCache()
Not available

And, for the NullCache:

let myCache = new NullCache();

Not available
myCache := cache.NewNullCache[any]()
Not available
my_cache = NullCache()
Not available

Store

We can cache a value by using the store() method. This method accepts four parameters. First, the context (trace_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(ctx, "key1", "ABC", 180000);  // Returns "ABC"

Not available
myCachedValue, _ := myCache.Store(context.Background(), "key1", "ABC", 180000) // Returns "ABC"
Not available
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 context (trace_id) and the cached value’s key as parameters. The code below shows how this method can be used.

let myRetrievedValue = await myCache.retrieve(ctx, "key1");  // Returns "ABC"

Not available
myRetrievedValue, _ := myCache.Retrieve(context.Background(), "key1") // Returns "ABC"
Not available
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 context (trace_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(ctx, "key1");

Not available
myCache.Remove(context.Background(), "key1")
Not available
my_cache.remove(None, "key1")
Not available

Moreover, if we want to retrieve the removed value:

Not available
Not available
myRetrievedValue, _ := myCache.Retrieve(context.Background(), "key1")
Not available
my_retrieved_value = my_cache.retrieve(None,"key1")
print(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.