@@ -5,13 +5,10 @@ import { Buffer } from 'node:buffer'
55import { join } from 'node:path'
66import { join as posixJoin } from 'node:path/posix'
77
8- import { purgeCache } from '@netlify/functions'
98import { type Span } from '@opentelemetry/api'
109import type { PrerenderManifest } from 'next/dist/build/index.js'
1110import { NEXT_CACHE_TAGS_HEADER } from 'next/dist/lib/constants.js'
1211
13- import { name as nextRuntimePkgName , version as nextRuntimePkgVersion } from '../../../package.json'
14- import { type TagManifest } from '../../shared/blob-types.cjs'
1512import {
1613 type CacheHandlerContext ,
1714 type CacheHandlerForMultipleVersions ,
@@ -28,10 +25,9 @@ import {
2825} from '../storage/storage.cjs'
2926
3027import { getLogger , getRequestContext } from './request-context.cjs'
28+ import { isAnyTagStale , markTagsAsStaleAndPurgeEdgeCache , purgeEdgeCache } from './tags-handler.cjs'
3129import { getTracer , recordWarning } from './tracer.cjs'
3230
33- const purgeCacheUserAgent = `${ nextRuntimePkgName } @${ nextRuntimePkgVersion } `
34-
3531export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
3632 options : CacheHandlerContext
3733 revalidatedTags : string [ ]
@@ -427,70 +423,15 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
427423 if ( requestContext ?. didPagesRouterOnDemandRevalidate ) {
428424 // encode here to deal with non ASCII characters in the key
429425 const tag = `_N_T_${ key === '/index' ? '/' : encodeURI ( key ) } `
430- const tags = tag . split ( / , | % 2 c / gi) . filter ( Boolean )
431-
432- if ( tags . length === 0 ) {
433- return
434- }
435426
436- getLogger ( ) . debug ( `Purging CDN cache for: [${ tag } ]` )
437- requestContext . trackBackgroundWork (
438- purgeCache ( { tags, userAgent : purgeCacheUserAgent } ) . catch ( ( error ) => {
439- // TODO: add reporting here
440- getLogger ( )
441- . withError ( error )
442- . error ( `[NetlifyCacheHandler]: Purging the cache for tag ${ tag } failed` )
443- } ) ,
444- )
427+ requestContext ?. trackBackgroundWork ( purgeEdgeCache ( tag ) )
445428 }
446429 }
447430 } )
448431 }
449432
450- // eslint-disable-next-line @typescript-eslint/no-explicit-any
451- async revalidateTag ( tagOrTags : string | string [ ] , ...args : any ) {
452- const revalidateTagPromise = this . doRevalidateTag ( tagOrTags , ...args )
453-
454- const requestContext = getRequestContext ( )
455- if ( requestContext ) {
456- requestContext . trackBackgroundWork ( revalidateTagPromise )
457- }
458-
459- return revalidateTagPromise
460- }
461-
462- // eslint-disable-next-line @typescript-eslint/no-explicit-any
463- private async doRevalidateTag ( tagOrTags : string | string [ ] , ...args : any ) {
464- getLogger ( ) . withFields ( { tagOrTags, args } ) . debug ( 'NetlifyCacheHandler.revalidateTag' )
465-
466- const tags = ( Array . isArray ( tagOrTags ) ? tagOrTags : [ tagOrTags ] )
467- . flatMap ( ( tag ) => tag . split ( / , | % 2 c / gi) )
468- . filter ( Boolean )
469-
470- if ( tags . length === 0 ) {
471- return
472- }
473-
474- const data : TagManifest = {
475- revalidatedAt : Date . now ( ) ,
476- }
477-
478- await Promise . all (
479- tags . map ( async ( tag ) => {
480- try {
481- await this . cacheStore . set ( tag , data , 'tagManifest.set' )
482- } catch ( error ) {
483- getLogger ( ) . withError ( error ) . log ( `Failed to update tag manifest for ${ tag } ` )
484- }
485- } ) ,
486- )
487-
488- await purgeCache ( { tags, userAgent : purgeCacheUserAgent } ) . catch ( ( error ) => {
489- // TODO: add reporting here
490- getLogger ( )
491- . withError ( error )
492- . error ( `[NetlifyCacheHandler]: Purging the cache for tags ${ tags . join ( ', ' ) } failed` )
493- } )
433+ async revalidateTag ( tagOrTags : string | string [ ] ) {
434+ return markTagsAsStaleAndPurgeEdgeCache ( tagOrTags )
494435 }
495436
496437 resetRequestCache ( ) {
@@ -501,7 +442,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
501442 /**
502443 * Checks if a cache entry is stale through on demand revalidated tags
503444 */
504- private async checkCacheEntryStaleByTags (
445+ private checkCacheEntryStaleByTags (
505446 cacheEntry : NetlifyCacheHandlerValue ,
506447 tags : string [ ] = [ ] ,
507448 softTags : string [ ] = [ ] ,
@@ -534,45 +475,8 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
534475 }
535476
536477 // 2. If any in-memory tags don't indicate that any of tags was invalidated
537- // we will check blob store. Full-route cache and fetch caches share a lot of tags
538- // but we will only do actual blob read once withing a single request due to cacheStore
539- // memoization.
540- // Additionally, we will resolve the promise as soon as we find first
541- // stale tag, so that we don't wait for all of them to resolve (but keep all
542- // running in case future `CacheHandler.get` calls would be able to use results).
543- // "Worst case" scenario is none of tag was invalidated in which case we need to wait
544- // for all blob store checks to finish before we can be certain that no tag is stale.
545- return new Promise < boolean > ( ( resolve , reject ) => {
546- const tagManifestPromises : Promise < boolean > [ ] = [ ]
547-
548- for ( const tag of cacheTags ) {
549- const tagManifestPromise : Promise < TagManifest | null > = this . cacheStore . get < TagManifest > (
550- tag ,
551- 'tagManifest.get' ,
552- )
553-
554- tagManifestPromises . push (
555- tagManifestPromise . then ( ( tagManifest ) => {
556- if ( ! tagManifest ) {
557- return false
558- }
559- const isStale = tagManifest . revalidatedAt >= ( cacheEntry . lastModified || Date . now ( ) )
560- if ( isStale ) {
561- resolve ( true )
562- return true
563- }
564- return false
565- } ) ,
566- )
567- }
568-
569- // make sure we resolve promise after all blobs are checked (if we didn't resolve as stale yet)
570- Promise . all ( tagManifestPromises )
571- . then ( ( tagManifestAreStale ) => {
572- resolve ( tagManifestAreStale . some ( ( tagIsStale ) => tagIsStale ) )
573- } )
574- . catch ( reject )
575- } )
478+ // we will check blob store.
479+ return isAnyTagStale ( cacheTags , cacheEntry . lastModified )
576480 }
577481}
578482
0 commit comments