@@ -5,13 +5,10 @@ import { Buffer } from 'node:buffer'
5
5
import { join } from 'node:path'
6
6
import { join as posixJoin } from 'node:path/posix'
7
7
8
- import { purgeCache } from '@netlify/functions'
9
8
import { type Span } from '@opentelemetry/api'
10
9
import type { PrerenderManifest } from 'next/dist/build/index.js'
11
10
import { NEXT_CACHE_TAGS_HEADER } from 'next/dist/lib/constants.js'
12
11
13
- import { name as nextRuntimePkgName , version as nextRuntimePkgVersion } from '../../../package.json'
14
- import { type TagManifest } from '../../shared/blob-types.cjs'
15
12
import {
16
13
type CacheHandlerContext ,
17
14
type CacheHandlerForMultipleVersions ,
@@ -28,10 +25,9 @@ import {
28
25
} from '../storage/storage.cjs'
29
26
30
27
import { getLogger , getRequestContext } from './request-context.cjs'
28
+ import { isAnyTagStale , markTagsAsStaleAndPurgeEdgeCache , purgeEdgeCache } from './tags-handler.cjs'
31
29
import { getTracer , recordWarning } from './tracer.cjs'
32
30
33
- const purgeCacheUserAgent = `${ nextRuntimePkgName } @${ nextRuntimePkgVersion } `
34
-
35
31
export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
36
32
options : CacheHandlerContext
37
33
revalidatedTags : string [ ]
@@ -427,70 +423,17 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
427
423
if ( requestContext ?. didPagesRouterOnDemandRevalidate ) {
428
424
// encode here to deal with non ASCII characters in the key
429
425
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
- }
435
426
436
427
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
- )
428
+
429
+ purgeEdgeCache ( tag )
445
430
}
446
431
}
447
432
} )
448
433
}
449
434
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
- } )
435
+ async revalidateTag ( tagOrTags : string | string [ ] ) {
436
+ return markTagsAsStaleAndPurgeEdgeCache ( tagOrTags )
494
437
}
495
438
496
439
resetRequestCache ( ) {
@@ -501,7 +444,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
501
444
/**
502
445
* Checks if a cache entry is stale through on demand revalidated tags
503
446
*/
504
- private async checkCacheEntryStaleByTags (
447
+ private checkCacheEntryStaleByTags (
505
448
cacheEntry : NetlifyCacheHandlerValue ,
506
449
tags : string [ ] = [ ] ,
507
450
softTags : string [ ] = [ ] ,
@@ -534,45 +477,8 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions {
534
477
}
535
478
536
479
// 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
- } )
480
+ // we will check blob store.
481
+ return isAnyTagStale ( cacheTags , cacheEntry . lastModified )
576
482
}
577
483
}
578
484
0 commit comments