@@ -8,9 +8,9 @@ type CachingClientType = RedisClientType<any, any, any, any, any>;
8
8
type CmdFunc = ( ) => Promise < ReplyUnion > ;
9
9
10
10
export interface ClientSideCacheConfig {
11
- ttl : number ;
12
- maxEntries : number ;
13
- lru : boolean ;
11
+ ttl ? : number ;
12
+ maxEntries ? : number ;
13
+ lru ? : boolean ;
14
14
}
15
15
16
16
type CacheCreator = {
@@ -48,7 +48,7 @@ export class ClientSideCacheEntryValue extends ClientSideCacheEntryBase {
48
48
readonly #value: any ;
49
49
50
50
get value ( ) {
51
- return structuredClone ( this . #value) ;
51
+ return this . #value;
52
52
}
53
53
54
54
constructor ( ttl : number , value : any ) {
@@ -79,7 +79,6 @@ export abstract class ClientSideCacheProvider extends EventEmitter {
79
79
abstract cacheMisses ( ) : number ;
80
80
abstract onError ( ) : void ;
81
81
abstract onClose ( ) : void ;
82
- abstract onDestroy ( ) : void ;
83
82
}
84
83
85
84
export class BasicClientSideCache extends ClientSideCacheProvider {
@@ -98,7 +97,7 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
98
97
this . #keyToCacheKeySetMap = new Map < string , Set < string > > ( ) ;
99
98
this . ttl = config ?. ttl ?? 0 ;
100
99
this . #maxEntries = config ?. maxEntries ?? 0 ;
101
- this . #lru = config ?. lru ?? false ;
100
+ this . #lru = config ?. lru ?? true ;
102
101
}
103
102
104
103
/* logic of how caching works:
@@ -123,7 +122,6 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
123
122
transformReply : TransformReply | undefined ,
124
123
typeMapping : TypeMapping | undefined
125
124
) {
126
- console . log ( "handleCache: enter" ) ;
127
125
let reply : ReplyUnion ;
128
126
129
127
const cacheKey = parser . cacheKey ;
@@ -133,10 +131,9 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
133
131
if ( cacheEntry ) {
134
132
// If instanceof is "too slow", can add a "type" and then use an "as" cast to call proper getters.
135
133
if ( cacheEntry instanceof ClientSideCacheEntryValue ) { // "2b1"
136
- console . log ( "returning value from cache" ) ;
137
134
this . #cacheHit( ) ;
138
135
139
- return cacheEntry . value ;
136
+ return structuredClone ( cacheEntry . value ) ;
140
137
} else if ( cacheEntry instanceof ClientSideCacheEntryPromise ) { // 2b2
141
138
// unsure if this should be considered a cache hit, a miss, or neither?
142
139
reply = await cacheEntry . promise ;
@@ -171,15 +168,14 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
171
168
// 3b
172
169
if ( cacheEntry . validate ( ) ) { // revalidating promise entry (dont save value, if promise entry has been invalidated)
173
170
// 3c
174
- console . log ( "saving value to cache" ) ;
175
171
cacheEntry = this . createValueEntry ( client , val ) ;
176
172
this . set ( cacheKey , cacheEntry , parser . keys ) ;
177
173
this . emit ( "cached-key" , cacheKey ) ;
178
174
} else {
179
- console . log ( "cache entry for key got invalidated between execution and saving, so not saving" ) ;
175
+ // console.log("cache entry for key got invalidated between execution and saving, so not saving");
180
176
}
181
177
182
- return val ;
178
+ return structuredClone ( val ) ;
183
179
}
184
180
185
181
override trackingOn ( ) {
@@ -189,21 +185,24 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
189
185
override invalidate ( key : RedisArgument | null ) {
190
186
if ( key === null ) {
191
187
this . clear ( false ) ;
188
+ this . emit ( "invalidate" , key ) ;
189
+
192
190
return ;
193
191
}
194
- const set = this . #keyToCacheKeySetMap . get ( key . toString ( ) ) ;
195
- if ( set ) {
196
- for ( const cacheKey of set ) {
197
- console . log ( `invalidate: got ${ cacheKey } from key ${ key . toString ( ) } set` ) ;
192
+
193
+ const keySet = this . #keyToCacheKeySetMap . get ( key . toString ( ) ) ;
194
+ if ( keySet ) {
195
+ for ( const cacheKey of keySet ) {
198
196
const entry = this . #cacheKeyToEntryMap. get ( cacheKey ) ;
199
197
if ( entry ) {
200
198
entry . invalidate ( ) ;
201
199
}
202
200
this . #cacheKeyToEntryMap. delete ( cacheKey ) ;
203
- this . emit ( "invalidate" , cacheKey ) ;
204
201
}
205
202
this . #keyToCacheKeySetMap. delete ( key . toString ( ) ) ;
206
203
}
204
+
205
+ this . emit ( 'invalidate' , key ) ;
207
206
}
208
207
209
208
override clear ( reset = true ) {
@@ -305,9 +304,9 @@ export class BasicClientSideCache extends ClientSideCacheProvider {
305
304
this . clear ( ) ;
306
305
}
307
306
308
- override onClose ( ) { }
309
-
310
- override onDestroy ( ) { }
307
+ override onClose ( ) {
308
+ this . clear ( ) ;
309
+ }
311
310
312
311
/**
313
312
* @internal
@@ -366,7 +365,11 @@ export abstract class PooledClientSideCacheProvider extends BasicClientSideCache
366
365
return super . has ( cacheKey ) ;
367
366
}
368
367
369
- onConnect ( factory : ( ) => CachingClientType ) { } ;
368
+ onPoolConnect ( factory : ( ) => CachingClientType ) { } ;
369
+
370
+ onPoolClose ( ) {
371
+ this . clear ( ) ;
372
+ } ;
370
373
}
371
374
372
375
// doesn't do anything special in pooling, clears cache on every client disconnect
@@ -382,6 +385,14 @@ export class BasicPooledClientSideCache extends PooledClientSideCacheProvider {
382
385
override removeClient ( client : CachingClientType ) : void {
383
386
return ;
384
387
}
388
+
389
+ override onError ( ) {
390
+ this . clear ( false ) ;
391
+ }
392
+
393
+ override onClose ( ) {
394
+ this . clear ( false ) ;
395
+ }
385
396
}
386
397
387
398
class PooledClientSideCacheEntryValue extends ClientSideCacheEntryValue {
@@ -443,7 +454,9 @@ export class PooledNoRedirectClientSideCache extends BasicPooledClientSideCache
443
454
}
444
455
445
456
// don't clear cache on error here
446
- override onError ( ) : void { }
457
+ override onError ( ) { }
458
+
459
+ override onClose ( ) { }
447
460
}
448
461
449
462
// Only clears cache on "management"/"redirect" client disconnect
@@ -482,7 +495,7 @@ export class PooledRedirectClientSideCache extends PooledClientSideCacheProvider
482
495
483
496
override onError ( ) : void { } ;
484
497
485
- override async onConnect ( factory : ( ) => CachingClientType ) {
498
+ override async onPoolConnect ( factory : ( ) => CachingClientType ) {
486
499
const client = factory ( ) ;
487
500
this . #redirectClient = client ;
488
501
@@ -502,20 +515,10 @@ export class PooledRedirectClientSideCache extends PooledClientSideCacheProvider
502
515
}
503
516
}
504
517
505
- onDestroy ( ) {
506
- this . clear ( ) ;
518
+ override onClose ( ) { } ;
507
519
508
- if ( this . #redirectClient) {
509
- this . #id = undefined ;
510
- const client = this . #redirectClient;
511
- this . #redirectClient = undefined ;
512
-
513
- client . destroy ( ) ;
514
- }
515
- }
516
-
517
- override async onClose ( ) {
518
- this . clear ( ) ;
520
+ override onPoolClose ( ) {
521
+ super . onPoolClose ( ) ;
519
522
520
523
if ( this . #redirectClient) {
521
524
this . #id = undefined ;
0 commit comments