1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import { logger } from '../logger';
import * as globalCache from '../util/cache/global';
/**
* Cache callback result which has to be returned by the `CacheCallback` function.
*/
export interface CacheResult<TResult = unknown> {
/**
* The data which should be added to the cache
*/
data: TResult;
/**
* `data` can only be cached if this is not `true`
*/
isPrivate?: boolean;
}
/**
* Simple helper type for defining the `CacheCallback` function return type
*/
export type CachePromise<TResult = unknown> = Promise<CacheResult<TResult>>;
/**
* The callback function which is called on cache miss.
*/
export type CacheCallback<TArg, TResult = unknown> = (
lookup: TArg
) => CachePromise<TResult>;
export type CacheConfig<TArg, TResult> = {
/**
* Datasource id
*/
id: string;
/**
* Cache key
*/
lookup: TArg;
/**
* Callback to use on cache miss to load result
*/
cb: CacheCallback<TArg, TResult>;
/**
* Time to cache result in minutes
*/
minutes?: number;
};
/**
* Loads result from cache or from passed callback on cache miss.
* @param param0 Cache config args
*/
export async function cacheAble<TArg, TResult = unknown>({
id,
lookup,
cb,
minutes = 60,
}: CacheConfig<TArg, TResult>): Promise<TResult> {
const cacheNamespace = `datasource-${id}`;
const cacheKey = JSON.stringify(lookup);
const cachedResult = await globalCache.get<TResult>(cacheNamespace, cacheKey);
// istanbul ignore if
if (cachedResult) {
logger.trace({ id, lookup }, 'datasource cachedResult');
return cachedResult;
}
const { data, isPrivate } = await cb(lookup);
// istanbul ignore if
if (isPrivate) {
logger.trace({ id, lookup }, 'Skipping datasource cache for private data');
} else {
await globalCache.set(cacheNamespace, cacheKey, data, minutes);
}
return data;
}
|