-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathUsdRepositoryCache.ts
More file actions
129 lines (110 loc) · 3.05 KB
/
UsdRepositoryCache.ts
File metadata and controls
129 lines (110 loc) · 3.05 KB
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { injectable } from 'inversify';
import {
PricePoint,
PriceStrategy,
UsdRepository,
deserializePricePoints,
serializePricePoints,
} from './UsdRepository';
import { CacheRepository } from '../CacheRepository/CacheRepository';
import { getCacheKey, PartialCacheKey } from '../../utils/cache';
const NULL_VALUE = 'null';
@injectable()
export class UsdRepositoryCache implements UsdRepository {
private baseCacheKey: PartialCacheKey[];
constructor(
private proxy: UsdRepository,
private cache: CacheRepository,
private cacheName: string,
private cacheTimeValueSeconds: number,
private cacheTimeNullSeconds: number
) {
this.baseCacheKey = ['repos', this.cacheName];
}
async getUsdPrice(
chainIdOrSlug: string,
tokenAddress?: string | undefined
): Promise<number | null> {
// Get price from cache
const key = getCacheKey(
...this.baseCacheKey,
'usd-price',
chainIdOrSlug,
tokenAddress || ''
);
const usdPriceCached = await this.getValueFromCache({
key,
convertFn: parseFloat,
});
if (usdPriceCached !== undefined) {
// Return cached price (if available)
return usdPriceCached;
}
// Get the usd Price (delegate call)
const usdPrice = await this.proxy.getUsdPrice(chainIdOrSlug, tokenAddress);
// Cache price (or absence of it)
this.cacheValue({
key,
value: usdPrice?.toString() || null,
});
return usdPrice;
}
async getUsdPrices(
chainIdOrSlug: string,
tokenAddress: string | undefined,
priceStrategy: PriceStrategy
): Promise<PricePoint[] | null> {
const key = getCacheKey(
...this.baseCacheKey,
'usd-prices',
chainIdOrSlug,
tokenAddress || '',
priceStrategy
);
// Get price from cache
const usdPriceCached = await this.getValueFromCache({
key,
convertFn: deserializePricePoints,
});
if (usdPriceCached !== undefined) {
// Return cached prices (if available)
return usdPriceCached;
}
// Get the usd Prices (delegate call)
const usdPrices = await this.proxy.getUsdPrices(
chainIdOrSlug,
tokenAddress,
priceStrategy
);
// Cache prices (or absence of it)
this.cacheValue({
key,
value: usdPrices ? serializePricePoints(usdPrices) : null,
});
return usdPrices;
}
private async getValueFromCache<T>(props: {
key: string;
convertFn: (value: string) => T;
}): Promise<T | null | undefined> {
const { key, convertFn } = props;
const valueString = await this.cache.get(key);
if (valueString) {
return valueString === NULL_VALUE ? null : convertFn(valueString);
}
return undefined;
}
private async cacheValue(props: {
key: string;
value: string | null;
}): Promise<void> {
const { key, value } = props;
const cacheTimeSeconds =
value === null ? this.cacheTimeNullSeconds : this.cacheTimeValueSeconds;
await this.cache.set(
key,
value === null ? NULL_VALUE : value,
cacheTimeSeconds
);
}
}