strapi-community/strapi-plugin-rest-cache

cache wont automatically purge after content type updated

yulafezmesi opened this issue · 4 comments

Hi, many thanks for this package. It might be a bug or just a quick question.

The cache data won't purge unless click Purge Rest Cache button on the list. Should it be done with a built-in config? Do we need an additional config to do that?

Cache type: Memory
Rest cache version: 4.1.0
Strapi version: 4.1.3
Node: v14.18.2

Hello @yulafezmesi
Can you enable debug mode with DEBUG=strapi:strapi-plugin-rest-cache yarn develop and share your plugin config ?
It will show you on which route purge middleware is registered, and also when a purge is emitted.

Here is the output:

{
 debug: false,
 enableEtag: false,
 enableXCacheHeaders: false,
 enableAdminCTBMiddleware: true,
 resetOnStartup: false,
 clearRelatedCache: true,
 maxAge: 3600000,
 keysPrefix: '',
 contentTypes: [
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::activity.activity',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::location.location',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::offer.offer',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::package.package',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::extra.extra',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::activity-provider.activity-provider',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::review.review',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::image.image',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::district.district',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::city.city',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::postal-code.postal-code',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::image-category.image-category',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::image-type.image-type',
     relatedContentTypeUid: [Array]
   },
   CacheContentTypeConfig {
     singleType: false,
     injectDefaultRoutes: true,
     maxAge: 3600000,
     hitpass: [Function: hitpass],
     keys: [CacheKeysConfig],
     plugin: undefined,
     routes: [Array],
     contentType: 'api::corona-opening-model.corona-opening-model',
     relatedContentTypeUid: [Array]
   }
 ],
 keys: CacheKeysConfig { useHeaders: [], useQueryParams: true }
}

It should also show you something like this on startup:

  strapi:strapi-plugin-rest-cache [REGISTER] api::homepage.homepage routes middlewares +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] GET /api/homepage recv maxAge=3600000 +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] api::global.global routes middlewares +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] GET /api/global recv maxAge=3600000 +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] api::page.page routes middlewares +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] GET /api/pages/slug/:uri+ recv maxAge=3600000 +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /api/pages purge +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] DELETE /api/pages/:id purge +1ms
  strapi:strapi-plugin-rest-cache [REGISTER] PUT /api/pages/:id purge +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] GET /api/pages recv maxAge=3600000 +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] GET /api/pages/:id recv maxAge=3600000 +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] admin routes middlewares +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/single-types/:model/actions/publish purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/single-types/:model/actions/unpublish purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/collection-types/:model purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/collection-types/:model/:id/actions/publish purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/collection-types/:model/:id/actions/unpublish purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] POST /content-manager/collection-types/:model/actions/bulkDelete purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] PUT /content-manager/single-types/:model purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] PUT /content-manager/collection-types/:model/:id purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] DELETE /content-manager/single-types/:model purge-admin +0ms
  strapi:strapi-plugin-rest-cache [REGISTER] DELETE /content-manager/collection-types/:model/:id purge-admin +1ms

and when you update an entity on the admin, you should see which keys are purged:

  strapi:strapi-plugin-rest-cache [PURGING KEY]: /api/pages?& +0ms
  strapi:strapi-plugin-rest-cache [PURGING KEY]: /api/pages/1?& +0ms
  strapi:strapi-plugin-rest-cache [PURGING KEY]: /api/pages/slug/example?& +0ms
[2022-03-09 15:06:21.557] http: PUT /content-manager/collection-types/api::page.page/1 (393 ms) 200

Also, can you share your plugin config form config/plugins.js?

I am having the same issue:

Here is the debug startup

{
    debug: false,
    enableEtag: false,
    enableXCacheHeaders: true,
    enableAdminCTBMiddleware: true,
    resetOnStartup: false,
    clearRelatedCache: true,
    maxAge: 3600000,
    keysPrefix: '',
    contentTypes: [
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::course.course',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::lesson.lesson',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::order.order',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::product.product',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::lead.lead',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::agent.agent',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::contact.contact',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::opportunity.opportunity',
        relatedContentTypeUid: [Array]
      },
      CacheContentTypeConfig {
        singleType: false,
        injectDefaultRoutes: true,
        maxAge: 3600000,
        hitpass: false,
        keys: [CacheKeysConfig],
        plugin: undefined,
        routes: [Array],
        contentType: 'api::account.account',
        relatedContentTypeUid: [Array]
      }
    ],
    keys: CacheKeysConfig { useHeaders: [], useQueryParams: true }
  }

Here is my response when I update the admin

[2022-03-09 15:18:23.612] http: GET /api/products?where%5Bwebsites%5D%5B%24in%5D%5B0%5D=6 (52 ms) 200
  strapi:strapi-plugin-rest-cache [RECV] GET /api/agents?filters={"contact":{"id":"1"}},populate="frc"& HIT +67ms
[2022-03-09 15:18:23.679] http: GET /api/agents?filters%5Bcontact%5D%5Bid%5D=1&populate=frc (50 ms) 200
[2022-03-09 15:20:20.187] http: PUT /content-manager/collection-types/api::agent.agent/1 (3789 ms) 200

Here is my config

module.exports = ({ env }) => ({
 redis: {
    config: {
      connections: {
        default: {
          connection: {
            host: config.host,
            port: config.port,
            user: config.user,
            db: 0,
            password: config.password,
          },
          settings: {
            debug: true,
            cluster: false,
          },
        }
      }
    }
  },
  "rest-cache": {
    config: {
      provider: {
        name: "redis",
        options: {
          max: 1000,
          connection: "default",
        },
      },
      strategy: {
        enableXCacheHeaders: true,
        hitpass: false,
        clearRelatedCache: true,
        contentTypes: [
          "api::course.course",
          "api::lesson.lesson",
          "api::product.product",
          "api::lead.lead",
          "api::agent.agent",
          "api::contact.contact",
          "api::opportunity.opportunity",
          "api::account.account"
        ]
      }
    }
  },
});

Hope this helps. I might have setup something wrong as well.