]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Invalidate cache feed even after server restart
authorChocobozzz <me@florianbigard.com>
Mon, 5 Jun 2023 08:05:49 +0000 (10:05 +0200)
committerChocobozzz <me@florianbigard.com>
Mon, 5 Jun 2023 08:05:49 +0000 (10:05 +0200)
server/middlewares/cache/shared/api-cache.ts
server/tests/feeds/feeds.ts

index c6197b97223e64923381310c63efada734a27258..b50b7dce4195f1350230a5d37b1b1f9fd45d2bda 100644 (file)
@@ -35,7 +35,11 @@ export class ApiCache {
   // Cache keys per group
   private groups: { [groupIndex: string]: string[] } = {}
 
+  private readonly seed: number
+
   constructor (options: APICacheOptions) {
+    this.seed = new Date().getTime()
+
     this.options = {
       headerBlacklist: [],
       excludeStatus: [],
@@ -88,7 +92,7 @@ export class ApiCache {
   }
 
   private getCacheKey (req: express.Request) {
-    return Redis.Instance.getPrefix() + 'api-cache-' + req.originalUrl
+    return Redis.Instance.getPrefix() + 'api-cache-' + this.seed + '-' + req.originalUrl
   }
 
   private shouldCacheResponse (response: express.Response) {
index 286c03596a12a1d5aab2157b953e9451d03157ac..8433c873e761b24b29e646935622b7810c414adc 100644 (file)
@@ -14,6 +14,7 @@ import {
   PluginsCommand,
   setAccessTokensToServers,
   setDefaultChannelAvatar,
+  setDefaultVideoChannel,
   stopFfmpeg,
   waitJobs
 } from '@shared/server-commands'
@@ -53,6 +54,7 @@ describe('Test syndication feeds', () => {
 
     await setAccessTokensToServers([ ...servers, serverHLSOnly ])
     await setDefaultChannelAvatar(servers[0])
+    await setDefaultVideoChannel(servers)
     await doubleFollow(servers[0], servers[1])
 
     await servers[0].config.enableLive({ allowReplay: false, transcoding: false })
@@ -137,28 +139,6 @@ describe('Test syndication feeds', () => {
       })
     })
 
-    it('Should serve the endpoint as a cached request', async function () {
-      const res = await makeGetRequest({
-        url: servers[0].url,
-        path: '/feeds/videos.xml',
-        accept: 'application/xml',
-        expectedStatus: HttpStatusCode.OK_200
-      })
-
-      expect(res.headers['x-api-cache-cached']).to.equal('true')
-    })
-
-    it('Should not serve the endpoint as a cached request', async function () {
-      const res = await makeGetRequest({
-        url: servers[0].url,
-        path: '/feeds/videos.xml?v=186',
-        accept: 'application/xml',
-        expectedStatus: HttpStatusCode.OK_200
-      })
-
-      expect(res.headers['x-api-cache-cached']).to.not.exist
-    })
-
     it('Should refuse to serve the endpoint without accept header', async function () {
       await makeGetRequest({ url: servers[0].url, path: '/feeds/videos.xml', expectedStatus: HttpStatusCode.NOT_ACCEPTABLE_406 })
     })
@@ -614,6 +594,92 @@ describe('Test syndication feeds', () => {
 
   })
 
+  describe('Cache', function () {
+    const uuids: string[] = []
+
+    function doPodcastRequest () {
+      return makeGetRequest({
+        url: servers[0].url,
+        path: '/feeds/podcast/videos.xml',
+        query: { videoChannelId: servers[0].store.channel.id },
+        accept: 'application/xml',
+        expectedStatus: HttpStatusCode.OK_200
+      })
+    }
+
+    function doVideosRequest (query: { [id: string]: string } = {}) {
+      return makeGetRequest({
+        url: servers[0].url,
+        path: '/feeds/videos.xml',
+        query,
+        accept: 'application/xml',
+        expectedStatus: HttpStatusCode.OK_200
+      })
+    }
+
+    before(async function () {
+      {
+        const { uuid } = await servers[0].videos.quickUpload({ name: 'cache 1' })
+        uuids.push(uuid)
+      }
+
+      {
+        const { uuid } = await servers[0].videos.quickUpload({ name: 'cache 2' })
+        uuids.push(uuid)
+      }
+    })
+
+    it('Should serve the videos endpoint as a cached request', async function () {
+      await doVideosRequest()
+
+      const res = await doVideosRequest()
+
+      expect(res.headers['x-api-cache-cached']).to.equal('true')
+    })
+
+    it('Should not serve the videos endpoint as a cached request', async function () {
+      const res = await doVideosRequest({ v: '186' })
+
+      expect(res.headers['x-api-cache-cached']).to.not.exist
+    })
+
+    it('Should invalidate the podcast feed cache after video deletion', async function () {
+      await doPodcastRequest()
+
+      {
+        const res = await doPodcastRequest()
+        expect(res.headers['x-api-cache-cached']).to.exist
+      }
+
+      await servers[0].videos.remove({ id: uuids[0] })
+
+      {
+        const res = await doPodcastRequest()
+        expect(res.headers['x-api-cache-cached']).to.not.exist
+      }
+    })
+
+    it('Should invalidate the podcast feed cache after video deletion, even after server restart', async function () {
+      this.timeout(120000)
+
+      await doPodcastRequest()
+
+      {
+        const res = await doPodcastRequest()
+        expect(res.headers['x-api-cache-cached']).to.exist
+      }
+
+      await servers[0].kill()
+      await servers[0].run()
+
+      await servers[0].videos.remove({ id: uuids[1] })
+
+      const res = await doPodcastRequest()
+      expect(res.headers['x-api-cache-cached']).to.not.exist
+    })
+
+  })
+
   after(async function () {
     await servers[0].plugins.uninstall({ npmName: 'peertube-plugin-test-podcast-custom-tags' })