1
1
import type { ComposableCacheEntry , ComposableCacheHandler } from "types/cache" ;
2
+ import { writeTags } from "utils/cache" ;
2
3
import { fromReadableStream , toReadableStream } from "utils/stream" ;
3
4
import { debug } from "./logger" ;
4
5
6
+ const pendingWritePromiseMap = new Map < string , Promise < ComposableCacheEntry > > ( ) ;
7
+
5
8
export default {
6
9
async get ( cacheKey : string ) {
7
10
try {
11
+ // We first check if we have a pending write for this cache key
12
+ // If we do, we return the pending promise instead of fetching the cache
13
+ if ( pendingWritePromiseMap . has ( cacheKey ) ) {
14
+ return pendingWritePromiseMap . get ( cacheKey ) ;
15
+ }
8
16
const result = await globalThis . incrementalCache . get (
9
17
cacheKey ,
10
18
"composable" ,
@@ -48,7 +56,10 @@ export default {
48
56
} ,
49
57
50
58
async set ( cacheKey : string , pendingEntry : Promise < ComposableCacheEntry > ) {
51
- const entry = await pendingEntry ;
59
+ pendingWritePromiseMap . set ( cacheKey , pendingEntry ) ;
60
+ const entry = await pendingEntry . finally ( ( ) => {
61
+ pendingWritePromiseMap . delete ( cacheKey ) ;
62
+ } ) ;
52
63
const valueToStore = await fromReadableStream ( entry . value ) ;
53
64
await globalThis . incrementalCache . set (
54
65
cacheKey ,
@@ -62,9 +73,7 @@ export default {
62
73
const storedTags = await globalThis . tagCache . getByPath ( cacheKey ) ;
63
74
const tagsToWrite = entry . tags . filter ( ( tag ) => ! storedTags . includes ( tag ) ) ;
64
75
if ( tagsToWrite . length > 0 ) {
65
- await globalThis . tagCache . writeTags (
66
- tagsToWrite . map ( ( tag ) => ( { tag, path : cacheKey } ) ) ,
67
- ) ;
76
+ await writeTags ( tagsToWrite . map ( ( tag ) => ( { tag, path : cacheKey } ) ) ) ;
68
77
}
69
78
}
70
79
} ,
@@ -83,7 +92,7 @@ export default {
83
92
} ,
84
93
async expireTags ( ...tags : string [ ] ) {
85
94
if ( globalThis . tagCache . mode === "nextMode" ) {
86
- return globalThis . tagCache . writeTags ( tags ) ;
95
+ return writeTags ( tags ) ;
87
96
}
88
97
const tagCache = globalThis . tagCache ;
89
98
const revalidatedAt = Date . now ( ) ;
@@ -104,7 +113,7 @@ export default {
104
113
for ( const entry of pathsToUpdate . flat ( ) ) {
105
114
setToWrite . add ( entry ) ;
106
115
}
107
- await globalThis . tagCache . writeTags ( Array . from ( setToWrite ) ) ;
116
+ await writeTags ( Array . from ( setToWrite ) ) ;
108
117
} ,
109
118
110
119
// This one is necessary for older versions of next
0 commit comments