11import type { KVNamespace } from '@cloudflare/workers-types' ;
22
3- import { CacheBackend , CacheEntry , CacheEntryMeta } from './types' ;
3+ import { CacheBackend , CacheEntry , CacheEntryLookup , CacheEntryMeta } from './types' ;
44import { getCacheMaxAge } from './utils' ;
55import { trace } from '../tracing' ;
66
7- const cacheVersion = 1 ;
7+ const cacheVersion = 2 ;
88
99interface KVTagMetadata {
1010 meta : CacheEntryMeta ;
1111}
1212
13- /**
14- * As we migrate off KV, we start disabling it for some tests content.
15- */
16- const noKVTags = new Set ( [
17- // docs.gitbook.com
18- 'url:docs.gitbook.com' ,
19- 'site:site_p4Xo4' ,
20- 'space:NkEGS7hzeqa35sMXQZ4X' ,
21- ] ) ;
22-
23- function shouldUseKVForTag ( tag : string ) : boolean {
24- if ( noKVTags . has ( tag ) ) {
25- return false ;
26- }
27- if ( tag . startsWith ( 'change-request:' ) ) {
28- return false ;
29- }
30-
31- // Hash the tag and return true for 95% of the tags
32- const hash = tag . split ( '' ) . reduce ( ( acc , char ) => {
33- return acc + char . charCodeAt ( 0 ) ;
34- } , 0 ) ;
35- if ( hash % 100 <= 30 ) {
36- return true ;
37- }
38-
39- return false ;
40- }
41-
4213/**
4314 * Cache implementation using the Cloudflare KV API.
4415 * https://developers.cloudflare.com/kv/
4516 */
4617export const cloudflareKVCache : CacheBackend = {
4718 name : 'cloudflare-kv' ,
4819 replication : 'global' ,
49- async get ( { key, tag } , options ) {
50- if ( tag && ! shouldUseKVForTag ( tag ) ) {
51- return null ;
52- }
53-
20+ async get ( entry , options ) {
5421 const kv = await getKVNamespace ( ) ;
5522 if ( ! kv ) {
5623 return null ;
@@ -59,19 +26,19 @@ export const cloudflareKVCache: CacheBackend = {
5926 return trace (
6027 {
6128 operation : `cloudflareKV.get` ,
62- name : key ,
29+ name : entry . key ,
6330 } ,
6431 async ( span ) => {
65- const kvKey = getValueKey ( key ) ;
32+ const kvKey = getKey ( entry ) ;
6633
67- const entry = await kv . get < CacheEntry > ( kvKey , {
34+ const kvEntry = await kv . get < CacheEntry > ( kvKey , {
6835 type : 'json' ,
6936 cacheTtl : 60 ,
7037 } ) ;
7138
72- span . setAttribute ( 'hit' , ! ! entry ) ;
39+ span . setAttribute ( 'hit' , ! ! kvEntry ) ;
7340
74- return entry ;
41+ return kvEntry ;
7542 } ,
7643 ) ;
7744 } ,
@@ -94,23 +61,10 @@ export const cloudflareKVCache: CacheBackend = {
9461 return ;
9562 }
9663
97- const kvKey = getValueKey ( entry . meta . key ) ;
64+ const kvKey = getKey ( entry . meta ) ;
9865 await kv . put ( kvKey , JSON . stringify ( entry ) , {
9966 expirationTtl : secondsFromNow ,
10067 } ) ;
101-
102- if ( entry . meta . tag ) {
103- const metadata : KVTagMetadata = {
104- meta : entry . meta ,
105- } ;
106- const jsonMetadata = JSON . stringify ( metadata ) ;
107- const tagKey = getTagKey ( entry . meta . tag , entry . meta . key ) ;
108-
109- await kv . put ( tagKey , jsonMetadata , {
110- metadata,
111- expirationTtl : secondsFromNow ,
112- } ) ;
113- }
11468 } ,
11569 ) ;
11670 } ,
@@ -121,8 +75,8 @@ export const cloudflareKVCache: CacheBackend = {
12175 }
12276
12377 await Promise . all (
124- entries . map ( async ( { key } ) => {
125- const kvKey = getValueKey ( key ) ;
78+ entries . map ( async ( entry ) => {
79+ const kvKey = getKey ( entry ) ;
12680 await kv . delete ( kvKey ) ;
12781 } ) ,
12882 ) ;
@@ -147,12 +101,7 @@ export const cloudflareKVCache: CacheBackend = {
147101 for ( const entry of entries . keys ) {
148102 if ( entry . metadata ) {
149103 const metadata = entry . metadata ;
150- const key = metadata . meta . key ;
151-
152104 result . push ( metadata . meta ) ;
153-
154- // Delete the tag key and the value key
155- pendingDeletions . push ( kv . delete ( getValueKey ( key ) ) ) ;
156105 pendingDeletions . push ( kv . delete ( entry . name ) ) ;
157106 }
158107 }
@@ -174,16 +123,12 @@ export const cloudflareKVCache: CacheBackend = {
174123 } ,
175124} ;
176125
177- function getValueKey ( key : string ) : string {
178- return `${ cacheVersion } .v. ${ key } ` ;
126+ function getKey ( entry : CacheEntryLookup ) {
127+ return `${ getTagPrefix ( entry . tag || 'default' ) } . ${ entry . key } ` ;
179128}
180129
181130function getTagPrefix ( tag : string ) {
182- return `${ cacheVersion } .tag.${ tag } .` ;
183- }
184-
185- function getTagKey ( tag : string , key : string ) {
186- return `${ getTagPrefix ( tag ) } ${ key } ` ;
131+ return `${ cacheVersion } .${ tag } .` ;
187132}
188133
189134async function getKVNamespace ( ) : Promise < KVNamespace | null > {
0 commit comments