]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/middlewares/cache/shared/api-cache.ts
Upgrade redis dep
[github/Chocobozzz/PeerTube.git] / server / middlewares / cache / shared / api-cache.ts
index f9f7b1b673406c2c0f0d83b90a46091bb4199fd5..86c5095b5fe402b730ddf34dbaa254df8145101a 100644 (file)
@@ -1,12 +1,13 @@
 // Thanks: https://github.com/kwhitley/apicache
 // We duplicated the library because it is unmaintened and prevent us to upgrade to recent NodeJS versions
 
-import * as express from 'express'
+import express from 'express'
 import { OutgoingHttpHeaders } from 'http'
 import { isTestInstance, parseDurationToMs } from '@server/helpers/core-utils'
 import { logger } from '@server/helpers/logger'
 import { Redis } from '@server/lib/redis'
 import { HttpStatusCode } from '@shared/models'
+import { asyncMiddleware } from '@server/middlewares'
 
 export interface APICacheOptions {
   headerBlacklist?: string[]
@@ -40,24 +41,25 @@ export class ApiCache {
   buildMiddleware (strDuration: string) {
     const duration = parseDurationToMs(strDuration)
 
-    return (req: express.Request, res: express.Response, next: express.NextFunction) => {
-      const key = Redis.Instance.getPrefix() + 'api-cache-' + req.originalUrl
-      const redis = Redis.Instance.getClient()
+    return asyncMiddleware(
+      async (req: express.Request, res: express.Response, next: express.NextFunction) => {
+        const key = Redis.Instance.getPrefix() + 'api-cache-' + req.originalUrl
+        const redis = Redis.Instance.getClient()
 
-      if (!redis.connected) return this.makeResponseCacheable(res, next, key, duration)
+        if (!Redis.Instance.isConnected()) return this.makeResponseCacheable(res, next, key, duration)
 
-      try {
-        redis.hgetall(key, (err, obj) => {
-          if (!err && obj && obj.response) {
+        try {
+          const obj = await redis.hGetAll(key)
+          if (obj?.response) {
             return this.sendCachedResponse(req, res, JSON.parse(obj.response), duration)
           }
 
           return this.makeResponseCacheable(res, next, key, duration)
-        })
-      } catch (err) {
-        return this.makeResponseCacheable(res, next, key, duration)
+        } catch (err) {
+          return this.makeResponseCacheable(res, next, key, duration)
+        }
       }
-    }
+    )
   }
 
   private shouldCacheResponse (response: express.Response) {
@@ -93,21 +95,22 @@ export class ApiCache {
     } as CacheObject
   }
 
-  private cacheResponse (key: string, value: object, duration: number) {
+  private async cacheResponse (key: string, value: object, duration: number) {
     const redis = Redis.Instance.getClient()
 
-    if (redis.connected) {
-      try {
-        redis.hset(key, 'response', JSON.stringify(value))
-        redis.hset(key, 'duration', duration + '')
+    if (Redis.Instance.isConnected()) {
+      await Promise.all([
+        redis.hSet(key, 'response', JSON.stringify(value)),
+        redis.hSet(key, 'duration', duration + ''),
         redis.expire(key, duration / 1000)
-      } catch (err) {
-        logger.error('Cannot set cache in redis.', { err })
-      }
+      ])
     }
 
     // add automatic cache clearing from duration, includes max limit on setTimeout
-    this.timers[key] = setTimeout(() => this.clear(key), Math.min(duration, 2147483647))
+    this.timers[key] = setTimeout(() => {
+      this.clear(key)
+        .catch(err => logger.error('Cannot clear Redis key %s.', key, { err }))
+    }, Math.min(duration, 2147483647))
   }
 
   private accumulateContent (res: express.Response, content: any) {
@@ -184,6 +187,7 @@ export class ApiCache {
             encoding
           )
           self.cacheResponse(key, cacheObject, duration)
+            .catch(err => logger.error('Cannot cache response', { err }))
         }
       }
 
@@ -235,7 +239,7 @@ export class ApiCache {
     return response.end(data, cacheObject.encoding)
   }
 
-  private clear (target: string) {
+  private async clear (target: string) {
     const redis = Redis.Instance.getClient()
 
     if (target) {
@@ -243,7 +247,7 @@ export class ApiCache {
       delete this.timers[target]
 
       try {
-        redis.del(target)
+        await redis.del(target)
       } catch (err) {
         logger.error('Cannot delete %s in redis cache.', target, { err })
       }
@@ -255,7 +259,7 @@ export class ApiCache {
         delete this.timers[key]
 
         try {
-          redis.del(key)
+          await redis.del(key)
         } catch (err) {
           logger.error('Cannot delete %s in redis cache.', key, { err })
         }