diff options
Diffstat (limited to 'server/middlewares/cache/shared/api-cache.ts')
-rw-r--r-- | server/middlewares/cache/shared/api-cache.ts | 50 |
1 files changed, 27 insertions, 23 deletions
diff --git a/server/middlewares/cache/shared/api-cache.ts b/server/middlewares/cache/shared/api-cache.ts index f8846dcfc..86c5095b5 100644 --- a/server/middlewares/cache/shared/api-cache.ts +++ b/server/middlewares/cache/shared/api-cache.ts | |||
@@ -7,6 +7,7 @@ import { isTestInstance, parseDurationToMs } from '@server/helpers/core-utils' | |||
7 | import { logger } from '@server/helpers/logger' | 7 | import { logger } from '@server/helpers/logger' |
8 | import { Redis } from '@server/lib/redis' | 8 | import { Redis } from '@server/lib/redis' |
9 | import { HttpStatusCode } from '@shared/models' | 9 | import { HttpStatusCode } from '@shared/models' |
10 | import { asyncMiddleware } from '@server/middlewares' | ||
10 | 11 | ||
11 | export interface APICacheOptions { | 12 | export interface APICacheOptions { |
12 | headerBlacklist?: string[] | 13 | headerBlacklist?: string[] |
@@ -40,24 +41,25 @@ export class ApiCache { | |||
40 | buildMiddleware (strDuration: string) { | 41 | buildMiddleware (strDuration: string) { |
41 | const duration = parseDurationToMs(strDuration) | 42 | const duration = parseDurationToMs(strDuration) |
42 | 43 | ||
43 | return (req: express.Request, res: express.Response, next: express.NextFunction) => { | 44 | return asyncMiddleware( |
44 | const key = Redis.Instance.getPrefix() + 'api-cache-' + req.originalUrl | 45 | async (req: express.Request, res: express.Response, next: express.NextFunction) => { |
45 | const redis = Redis.Instance.getClient() | 46 | const key = Redis.Instance.getPrefix() + 'api-cache-' + req.originalUrl |
47 | const redis = Redis.Instance.getClient() | ||
46 | 48 | ||
47 | if (!redis.connected) return this.makeResponseCacheable(res, next, key, duration) | 49 | if (!Redis.Instance.isConnected()) return this.makeResponseCacheable(res, next, key, duration) |
48 | 50 | ||
49 | try { | 51 | try { |
50 | redis.hgetall(key, (err, obj) => { | 52 | const obj = await redis.hGetAll(key) |
51 | if (!err && obj && obj.response) { | 53 | if (obj?.response) { |
52 | return this.sendCachedResponse(req, res, JSON.parse(obj.response), duration) | 54 | return this.sendCachedResponse(req, res, JSON.parse(obj.response), duration) |
53 | } | 55 | } |
54 | 56 | ||
55 | return this.makeResponseCacheable(res, next, key, duration) | 57 | return this.makeResponseCacheable(res, next, key, duration) |
56 | }) | 58 | } catch (err) { |
57 | } catch (err) { | 59 | return this.makeResponseCacheable(res, next, key, duration) |
58 | return this.makeResponseCacheable(res, next, key, duration) | 60 | } |
59 | } | 61 | } |
60 | } | 62 | ) |
61 | } | 63 | } |
62 | 64 | ||
63 | private shouldCacheResponse (response: express.Response) { | 65 | private shouldCacheResponse (response: express.Response) { |
@@ -93,21 +95,22 @@ export class ApiCache { | |||
93 | } as CacheObject | 95 | } as CacheObject |
94 | } | 96 | } |
95 | 97 | ||
96 | private cacheResponse (key: string, value: object, duration: number) { | 98 | private async cacheResponse (key: string, value: object, duration: number) { |
97 | const redis = Redis.Instance.getClient() | 99 | const redis = Redis.Instance.getClient() |
98 | 100 | ||
99 | if (redis.connected) { | 101 | if (Redis.Instance.isConnected()) { |
100 | try { | 102 | await Promise.all([ |
101 | redis.hset(key, 'response', JSON.stringify(value)) | 103 | redis.hSet(key, 'response', JSON.stringify(value)), |
102 | redis.hset(key, 'duration', duration + '') | 104 | redis.hSet(key, 'duration', duration + ''), |
103 | redis.expire(key, duration / 1000) | 105 | redis.expire(key, duration / 1000) |
104 | } catch (err) { | 106 | ]) |
105 | logger.error('Cannot set cache in redis.', { err }) | ||
106 | } | ||
107 | } | 107 | } |
108 | 108 | ||
109 | // add automatic cache clearing from duration, includes max limit on setTimeout | 109 | // add automatic cache clearing from duration, includes max limit on setTimeout |
110 | this.timers[key] = setTimeout(() => this.clear(key), Math.min(duration, 2147483647)) | 110 | this.timers[key] = setTimeout(() => { |
111 | this.clear(key) | ||
112 | .catch(err => logger.error('Cannot clear Redis key %s.', key, { err })) | ||
113 | }, Math.min(duration, 2147483647)) | ||
111 | } | 114 | } |
112 | 115 | ||
113 | private accumulateContent (res: express.Response, content: any) { | 116 | private accumulateContent (res: express.Response, content: any) { |
@@ -184,6 +187,7 @@ export class ApiCache { | |||
184 | encoding | 187 | encoding |
185 | ) | 188 | ) |
186 | self.cacheResponse(key, cacheObject, duration) | 189 | self.cacheResponse(key, cacheObject, duration) |
190 | .catch(err => logger.error('Cannot cache response', { err })) | ||
187 | } | 191 | } |
188 | } | 192 | } |
189 | 193 | ||
@@ -235,7 +239,7 @@ export class ApiCache { | |||
235 | return response.end(data, cacheObject.encoding) | 239 | return response.end(data, cacheObject.encoding) |
236 | } | 240 | } |
237 | 241 | ||
238 | private clear (target: string) { | 242 | private async clear (target: string) { |
239 | const redis = Redis.Instance.getClient() | 243 | const redis = Redis.Instance.getClient() |
240 | 244 | ||
241 | if (target) { | 245 | if (target) { |
@@ -243,7 +247,7 @@ export class ApiCache { | |||
243 | delete this.timers[target] | 247 | delete this.timers[target] |
244 | 248 | ||
245 | try { | 249 | try { |
246 | redis.del(target) | 250 | await redis.del(target) |
247 | } catch (err) { | 251 | } catch (err) { |
248 | logger.error('Cannot delete %s in redis cache.', target, { err }) | 252 | logger.error('Cannot delete %s in redis cache.', target, { err }) |
249 | } | 253 | } |
@@ -255,7 +259,7 @@ export class ApiCache { | |||
255 | delete this.timers[key] | 259 | delete this.timers[key] |
256 | 260 | ||
257 | try { | 261 | try { |
258 | redis.del(key) | 262 | await redis.del(key) |
259 | } catch (err) { | 263 | } catch (err) { |
260 | logger.error('Cannot delete %s in redis cache.', key, { err }) | 264 | logger.error('Cannot delete %s in redis cache.', key, { err }) |
261 | } | 265 | } |