Skip to content

Commit 456b4e3

Browse files
committed
Tydelig paths vs cache keys
1 parent 9d2c924 commit 456b4e3

File tree

3 files changed

+51
-45
lines changed

3 files changed

+51
-45
lines changed

server/src/cache/page-cache-handler.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CacheHandlerValue } from 'next/dist/server/lib/incremental-cache';
44
import { RedisCache } from 'srcCommon/redis';
55
import { isLeaderPod } from 'leader-pod';
66
import { CACHE_TTL_24_HOURS_IN_MS } from 'srcCommon/constants';
7+
import { pathToCacheKey } from 'srcCommon/cache-key';
78

89
const TTL_RESOLUTION_MS = 60 * 1000;
910

@@ -17,14 +18,14 @@ const localCache = new LRUCache<string, CacheHandlerValue>({
1718

1819
export default class PageCacheHandler {
1920
public async get(...args: Parameters<FileSystemCache['get']>) {
20-
const [key] = args;
21+
const [path] = args;
2122

22-
const fromLocalCache = localCache.get(key);
23+
const fromLocalCache = localCache.get(path);
2324
if (fromLocalCache) {
2425
return fromLocalCache;
2526
}
2627

27-
const fromRedisCache = await redisCache.getRender(key);
28+
const fromRedisCache = await redisCache.getRender(path);
2829
if (!fromRedisCache) {
2930
return null;
3031
}
@@ -36,7 +37,7 @@ export default class PageCacheHandler {
3637
: CACHE_TTL_24_HOURS_IN_MS;
3738

3839
if (ttlRemaining > TTL_RESOLUTION_MS) {
39-
localCache.set(key, fromRedisCache, {
40+
localCache.set(path, fromRedisCache, {
4041
ttl: ttlRemaining,
4142
});
4243
}
@@ -45,15 +46,15 @@ export default class PageCacheHandler {
4546
}
4647

4748
public async set(...args: Parameters<FileSystemCache['set']>) {
48-
const [key, data] = args;
49+
const [path, data] = args;
4950

5051
const cacheItem: CacheHandlerValue = {
5152
value: data,
5253
lastModified: Date.now(),
5354
};
5455

55-
localCache.set(key, cacheItem);
56-
redisCache.setRender(key, cacheItem);
56+
localCache.set(path, cacheItem);
57+
redisCache.setRender(path, cacheItem);
5758
}
5859

5960
public async clear() {
@@ -65,11 +66,10 @@ export default class PageCacheHandler {
6566
}
6667

6768
public async delete(path: string) {
68-
const pagePath = path === '/' ? '/index' : path;
69-
localCache.delete(pagePath);
69+
localCache.delete(pathToCacheKey(path));
7070

7171
if (await isLeaderPod()) {
72-
return redisCache.delete(pagePath);
72+
return redisCache.delete(path);
7373
}
7474
}
7575
}

srcCommon/cache-key.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const pathToCacheKey = (path: string) =>
2+
path === '/' ? '/index' : path;

srcCommon/redis.ts

+39-35
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { logger } from 'srcCommon/logger';
33
import { PHASE_PRODUCTION_BUILD } from 'next/constants';
44
import { CACHE_TTL_24_HOURS_IN_MS } from 'srcCommon/constants';
55
import { CacheHandlerValue } from 'next/dist/server/lib/incremental-cache';
6+
import { pathToCacheKey } from 'srcCommon/cache-key';
67

78
// TODO: share XP response props with next-app for a proper type here
89
type XpResponseProps = Record<string, any>;
@@ -31,24 +32,24 @@ const validateClientOptions = () => {
3132
interface IRedisCache {
3233
init(buildId: string): Promise<IRedisCache>;
3334

34-
getRender(key: string): Promise<CacheHandlerValue | null>;
35+
getRender(path: string): Promise<CacheHandlerValue | null>;
3536

36-
setRender(key: string, data: CacheHandlerValue): Promise<string | null>;
37+
setRender(path: string, data: CacheHandlerValue): Promise<string | null>;
3738

38-
getResponse(key: string): Promise<XpResponseProps | null>;
39+
getResponse(path: string): Promise<XpResponseProps | null>;
3940

40-
setResponse(key: string, data: XpResponseProps): Promise<string | null>;
41+
setResponse(path: string, data: XpResponseProps): Promise<string | null>;
4142

42-
delete(key: string): Promise<number>;
43+
delete(path: string): Promise<number>;
4344

4445
clear(): Promise<string>;
4546
}
4647

4748
class RedisCacheImpl implements IRedisCache {
4849
private readonly client: ReturnType<typeof createClient>;
4950
private readonly ttl: number = CACHE_TTL_24_HOURS_IN_MS;
50-
private readonly responseCachePrefix = `${process.env.ENV}:xp-response`;
51-
private renderCachePrefix = '';
51+
private readonly responseCacheKeyPrefix = `${process.env.ENV}:xp-response`;
52+
private renderCacheKeyPrefix = '';
5253

5354
constructor() {
5455
this.client = createClient(clientOptions)
@@ -70,70 +71,73 @@ class RedisCacheImpl implements IRedisCache {
7071
}
7172

7273
public async init(buildId: string) {
73-
this.renderCachePrefix = `${process.env.ENV}:render:${buildId}`;
74+
this.renderCacheKeyPrefix = `${process.env.ENV}:render:${buildId}`;
7475

7576
return this.client.connect().then(() => {
7677
logger.info(
77-
`Initialized redis client with url ${clientOptions.url} - TTL: ${this.ttl} - Render prefix: ${this.renderCachePrefix} - Response prefix: ${this.responseCachePrefix}`
78+
`Initialized redis client with url ${clientOptions.url} - TTL: ${this.ttl} - Render prefix: ${this.renderCacheKeyPrefix} - Response prefix: ${this.responseCacheKeyPrefix}`
7879
);
7980
return this;
8081
});
8182
}
8283

83-
private async get(key: string) {
84+
private async get(path: string) {
8485
return this.client
85-
.get(key)
86+
.get(path)
8687
.then((result) => (result ? JSON.parse(result) : result))
8788
.catch((e) => {
88-
logger.error(`Error getting value for key ${key} - ${e}`);
89+
logger.error(`Error getting value for path ${path} - ${e}`);
8990
return Promise.resolve(null);
9091
});
9192
}
9293

93-
public async getRender(key: string) {
94-
return this.get(this.getPrefixedKey(key, this.renderCachePrefix));
94+
public async getRender(path: string) {
95+
return this.get(this.getCacheKey(path, this.renderCacheKeyPrefix));
9596
}
9697

97-
public async getResponse(key: string) {
98-
return this.get(this.getPrefixedKey(key, this.responseCachePrefix));
98+
public async getResponse(path: string) {
99+
return this.get(this.getCacheKey(path, this.responseCacheKeyPrefix));
99100
}
100101

101-
private async set<DataType>(key: string, data: DataType) {
102+
private async set<DataType>(path: string, data: DataType) {
102103
return this.client
103-
.set(key, JSON.stringify(data), {
104+
.set(path, JSON.stringify(data), {
104105
PX: this.ttl,
105106
})
106107
.then((result) => {
107-
logger.info(`Redis set result for ${key}: ${result}`);
108+
logger.info(`Redis set result for ${path}: ${result}`);
108109
return result;
109110
})
110111
.catch((e) => {
111-
logger.error(`Error setting value for key ${key} - ${e}`);
112+
logger.error(`Error setting value for path ${path} - ${e}`);
112113
return Promise.resolve(null);
113114
});
114115
}
115116

116-
public async setRender(key: string, data: CacheHandlerValue) {
117-
return this.set(this.getPrefixedKey(key, this.renderCachePrefix), data);
117+
public async setRender(path: string, data: CacheHandlerValue) {
118+
return this.set(
119+
this.getCacheKey(path, this.renderCacheKeyPrefix),
120+
data
121+
);
118122
}
119123

120-
public async setResponse(key: string, data: XpResponseProps) {
124+
public async setResponse(path: string, data: XpResponseProps) {
121125
return this.set(
122-
this.getPrefixedKey(key, this.responseCachePrefix),
126+
this.getCacheKey(path, this.responseCacheKeyPrefix),
123127
data
124128
);
125129
}
126130

127-
public async delete(key: string) {
128-
const responseKey = this.getPrefixedKey(key, this.responseCachePrefix);
129-
const renderKey = this.getPrefixedKey(key, this.renderCachePrefix);
131+
public async delete(path: string) {
132+
const responseKey = this.getCacheKey(path, this.responseCacheKeyPrefix);
133+
const renderKey = this.getCacheKey(path, this.renderCacheKeyPrefix);
130134

131135
logger.info(
132136
`Deleting redis cache entries for ${responseKey} and ${renderKey}`
133137
);
134138

135139
return this.client.del([responseKey, renderKey]).catch((e) => {
136-
logger.error(`Error deleting value for key ${key} - ${e}`);
140+
logger.error(`Error deleting value for path ${path} - ${e}`);
137141
return 0;
138142
});
139143
}
@@ -147,8 +151,8 @@ class RedisCacheImpl implements IRedisCache {
147151
});
148152
}
149153

150-
private getPrefixedKey(key: string, keyPrefix: string) {
151-
return `${keyPrefix}:${key}`;
154+
private getCacheKey(path: string, keyPrefix: string) {
155+
return `${keyPrefix}:${pathToCacheKey(path)}`;
152156
}
153157
}
154158

@@ -157,23 +161,23 @@ class RedisCacheDummy implements IRedisCache {
157161
return this;
158162
}
159163

160-
public async getRender(key: string) {
164+
public async getRender(path: string) {
161165
return null;
162166
}
163167

164-
public async getResponse(key: string) {
168+
public async getResponse(path: string) {
165169
return null;
166170
}
167171

168-
public async setRender(key: string, data: CacheHandlerValue) {
172+
public async setRender(path: string, data: CacheHandlerValue) {
169173
return null;
170174
}
171175

172-
public async setResponse(key: string, data: XpResponseProps) {
176+
public async setResponse(path: string, data: XpResponseProps) {
173177
return null;
174178
}
175179

176-
public async delete(key: string) {
180+
public async delete(path: string) {
177181
return 1;
178182
}
179183

0 commit comments

Comments
 (0)