Skip to content

Instantly share code, notes, and snippets.

@anushshukla
Last active December 26, 2022 06:32
Show Gist options
  • Select an option

  • Save anushshukla/0d2bbd14c716fa0897a3808a4dc94166 to your computer and use it in GitHub Desktop.

Select an option

Save anushshukla/0d2bbd14c716fa0897a3808a4dc94166 to your computer and use it in GitHub Desktop.
Caching solutions
import httpAdapter from 'axios/lib/adapters/http';
import settle from 'axios/lib/core/settle';
const getApiResponse = ({ cachedKeyName, config }) =>
new Promise((resolve, reject) =>
httpAdapter(config).then(response => {
if (response.status === 200) {
localStorage.setItem(cacheKeyName, response);
}
settle(resolve, reject, response);
}).catch(reject);
const getCachedApiResponse = config =>
new Promise((resolve, reject) => {
const cacheKeyName = bota(JSON.stringify({
baseURL: config.baseURL, // API host
url: config.url, // API endpoint
params: config.params, // Query Params
data: config.data, // Request body
// headers: config.headers, // Request headers
}));
const cachedApiResponse = localStorage.getItem(cacheKeyName);
if (cachedApiResponse) {
getApiResponse(cacheKeyName)(config); // this can be removed if we are sure about cache invalidation mechanism
return resolve(cachedApiResponse);
}
return getApiResponse({ cacheKeyName, config });
});
// Usage example
// pass { adapter: customAdapter } to axios.create()
// use it wherever required

Problem statement

When the system performs not upto expectation in terms of UX or/and system resources utilisation.

Solutions

When to apply cache?

We need to cache data when its fetching consumes a lot of machine resources and response time doesn't meet expectation while its frequently not updated & frequently requested

What should be the cache key name?

It needs to be unique and concise.

How to cache refresh?

Cache refresh

We must be able to refresh the cached data when its original data is updated.

When to delete cache?

When the cached data is not required or not in use.

In extrememe cases, where the memory is getting overconsumed and we don't have the luxury to increase the memory

How to implement cache?

The quickest way to implement cache at first would be to add cache and in the background update the cache, this would improve the response time but not the matchine's resources consumption but slowly and steadily, when cache refresh / delete is implement then this background cache can be disabled.

The cache ideally should be centralised and distributed (scalable) like Redis with CDN to improved upon latency due to geo location.

The following are the implementation of caching at different layers.

Data layer (Data sources)

SQL (MySQL, Postgres, Oracle, etc) databases query caching using Prepared statements.

Application layer (Frontend)

We can implement memoisation to cache eligible API, CPU intensive functions, etc.

Model

Most of the ORM / ODM provides the ability to cache database query result with flexibility.

It's advisable that CDC (like Debezium) to be implemented for cache delete.

API

We can cache the API response in the background after the request is sent and this cache can be refereshed whenever its response source of data are updated.

Presentation layer (Frontend)

When the FE makes request to BE, the response can be cached.

The FE can call a BE API when the app boots with the list of cache and its minium details and the BE can respond a list of cache needs to be re-generated at FE.

function myMemoize(fn) {
const caches = {} as Record<string, any>;
return async (...args) => {
const cacheKeyName = JSON.stringify(args);
const cache = caches[cacheKeyName];
if (cache) {
console.log('cached value');
return cache;
}
const output = await fn(...args);
caches[cacheKeyName] = output;
return output;
}
}
const sum = (a,b) => a+b;
const memoizedSum = myMemoize(sum);
memoizedSum(2,3);
memoizedSum(2,3);
const fetchData = async (x,y) => {
return setTimeout(() => {
return 'hi';
}, 1000)
}
const memoizedFetchData = myMemoize(fetchData);
memoizedFetchData(2,3)
.then((resp) => {});
memoizedFetchData(2,3)
.then((resp) => {});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment