Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on-demand cache revalidation/incremental static genration #889

Open
1 task
anuragkumar19 opened this issue Jan 27, 2023 · 9 comments
Open
1 task

on-demand cache revalidation/incremental static genration #889

anuragkumar19 opened this issue Jan 27, 2023 · 9 comments
Labels
discussion enhancement New feature or request

Comments

@anuragkumar19
Copy link

Describe the feature

Hi!
The feature is to add a global function revalidate which can be called with path argument to revalidate the cache of a specific path. Ex: Initially route have {static:true} and in API route we can do revalidate('/blog'), revalidate('/blog/posts/1').

It will be useful for CMS and can be used with webhook to see instant changes.

This feature can further be extended in nuxt for on-demand incremental static generation.

This can be further simplified by providing a default route /__nuxt/revalidate/ or '__nitro/revalidate' with path='...' to revalidate the route. Of course, user can add middleware to secure the route to verify the request is coming from CMS.

Additional information

  • Would you be willing to help implement this feature?
@pi0
Copy link
Member

pi0 commented Jan 27, 2023

For incremental, we might use swr: true route rule it will presrve routes in filesystem/memory cache on demand and runtime. (static files cannot be removed from provider)

Assuming using cache API, You can create a server route (and protect it however you like) to clear cache using something like this:

export default eventHandler(async event => {
  // TODO: Protect route
  const storage = useStorage()
  const cacheKeys = await storage.getKeys('cache/nitro')
  await Promise.all(cacheKeys.map(key => storage.removeItem(key)))
  return { clearedItems: cacheKeys.length }
})

Can you try it and if found useful maybe we can make a built-in util for clearCache(prefix)

@pi0 pi0 added enhancement New feature or request discussion and removed pending triage labels Jan 27, 2023
@ghost
Copy link

ghost commented Jan 27, 2023

I proposed something similar here: #716
I built two utils: createSwrCache and revalidateSwrCache
stackblitz: https://stackblitz.com/edit/github-xc6cjm-qscwkg?file=utils/swrRevalidate.ts

@pi0
Copy link
Member

pi0 commented Jan 27, 2023

Nice! What would be the usage of createSwrCache? (cache entries are internally and automatically created and managed)

We might expose two new utils, clearCache(prefix) (it is not essentially swr) and prefetchRoutes(routes: []) . Wdyt?

@ghost
Copy link

ghost commented Jan 27, 2023

At that time I wanted to make a constistent way of configuring the cache-key for the storage-value with createSwrCache, which in turn made it clear what to target with revalidateSwrCache.
But now I think it could be easier to have have a clearCache function on a cachedEventHandler itself.

 // routes/<route>.ts
export default cachedEventHandler(
  async () => {
    new Promise((resolve) => setTimeout(resolve, 1000));
    console.log('index');
    return `Response generated at ${new Date().toISOString()}`;
  },
  {
    swr: true,
    maxAge: 500000,
  }
);

And then import it elsewhere:

 // routes/<reval-route>.ts
import routeHandler from './<route>.ts'
export default defineEventHandler((event) => {
     routeHandler.clearCache()
});

The same might also be applicable to cachedFunction

Either that or a function that simply takes in a route-path.

@anuragkumar19
Copy link
Author

@pi0 The above code you have given is invalidating all cache. It will be nice to have utils to invalidate specific cache.

Any reference to how cache key are generated?

@anuragkumar19
Copy link
Author

anuragkumar19 commented Jan 27, 2023

I found it.
https://github.com/unjs/nitro/blob/main/src/runtime/cache.ts#L177

Its ${first_16_character_of_url_path}.${hashed_path}

@anuragkumar19
Copy link
Author

anuragkumar19 commented Jan 28, 2023

While going through issues and pull requests I found that It was planned but never implemented
#545 (comment)

Edit:
Can we ask danielroe he said that he had already a local prove-of-concept

@hcmlopes
Copy link
Contributor

While going through issues and pull requests I found that It was planned but never implemented #545 (comment)

Edit: Can we ask danielroe he said that he had already a local prove-of-concept

I think the discussion mention which is happening on PR #545 is not quite what is being discussed here. I believe the discussions in that PR are specific to Vercel's cache and if so then I think this latest 3.7 release should have handled those requirements based on a PR of my own here #1723

I do think this specific on demand nitro cache invalidation still needs to be worked on. If Pooya provides some more detail I am willing to work on this, I am just a bit confused about this comment and what exactly prefetchRoutes(routes: []) would be doing or how it would work

@bernhardberger
Copy link

bernhardberger commented Dec 30, 2023

I've been looking at a solution for this myself recently. Imho it needs to be based on cache tags like in the https://github.com/dulnan/nuxt-multi-cache module.

That way one could leverage cache tags (e.g. Job Postings that are displayed and linked on several different pages/routes) and clear the associated cache tags from a CMS etc without having to know the exact routes the frontend is rendering that content (which is basically impossible to keep track of in larger projects where the editor is responsible for composing pages in the CMS)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants