@@ -132,6 +132,17 @@ type CacheEntry = {
132132 renewalKey : string ;
133133} ;
134134
135+ type CheckCacheOptions = {
136+ renewalKey : string ;
137+ renewalThreshold : number ;
138+ expiration : number ;
139+ options : CacheQueryResultOptions ;
140+ spanId : string ;
141+ cacheKey : CacheKey ;
142+ primaryQuery : boolean ;
143+ renewCycle : boolean ;
144+ } ;
145+
135146export interface QueryCacheOptions {
136147 refreshKeyRenewalThreshold ?: number ;
137148 externalQueueOptions ?: any ;
@@ -857,6 +868,66 @@ export class QueryCache {
857868 callback : ( ) => MaybeCancelablePromise < T > ,
858869 ) => this . cacheDriver . withLock ( `lock:${ key } ` , callback , ttl , true ) ;
859870
871+ protected async checkInCache (
872+ redisKey : string ,
873+ opts : CheckCacheOptions
874+ ) : Promise < any > {
875+ // First check in-memory cache if enabled
876+ if ( opts . options . useInMemory ) {
877+ const inMemoryResult = this . checkInMemoryCache ( redisKey , opts ) ;
878+
879+ if ( inMemoryResult ) {
880+ return inMemoryResult ;
881+ }
882+ }
883+
884+ // If not found in memory, check cache driver
885+ return this . cacheDriver . get ( redisKey ) ;
886+ }
887+
888+ protected checkInMemoryCache (
889+ redisKey : string ,
890+ opts : CheckCacheOptions
891+ ) : any {
892+ const inMemoryCacheDisablePeriod = 5 * 60 * 1000 ;
893+
894+ const inMemoryValue = this . memoryCache . get ( redisKey ) ;
895+ if ( ! inMemoryValue ) {
896+ return null ;
897+ }
898+
899+ const renewedAgo = ( new Date ( ) ) . getTime ( ) - inMemoryValue . time ;
900+
901+ if (
902+ opts . renewalKey && (
903+ ! opts . renewalThreshold ||
904+ ! inMemoryValue . time ||
905+ // Do not cache in memory in last 5 minutes of expiry.
906+ // Most likely it'll cause race condition of refreshing data with different refreshKey values.
907+ renewedAgo + inMemoryCacheDisablePeriod > opts . renewalThreshold * 1000 ||
908+ inMemoryValue . renewalKey !== opts . renewalKey
909+ ) || renewedAgo > opts . expiration * 1000 || renewedAgo > inMemoryCacheDisablePeriod
910+ ) {
911+ this . memoryCache . delete ( redisKey ) ;
912+ return null ;
913+ }
914+
915+ this . logger ( 'Found in memory cache entry' , {
916+ cacheKey : opts . cacheKey ,
917+ time : inMemoryValue . time ,
918+ renewedAgo,
919+ renewalKey : inMemoryValue . renewalKey ,
920+ newRenewalKey : opts . renewalKey ,
921+ renewalThreshold : opts . renewalThreshold ,
922+ requestId : opts . options . requestId ,
923+ spanId : opts . spanId ,
924+ primaryQuery : opts . primaryQuery ,
925+ renewCycle : opts . renewCycle
926+ } ) ;
927+
928+ return inMemoryValue ;
929+ }
930+
860931 public async cacheQueryResult (
861932 query : string | QueryWithParams ,
862933 values : string [ ] ,
@@ -928,56 +999,27 @@ export class QueryCache {
928999 return fetchNew ( ) ;
9291000 }
9301001
931- let res ;
932-
933- const inMemoryCacheDisablePeriod = 5 * 60 * 1000 ;
934-
935- if ( options . useInMemory ) {
936- const inMemoryValue = this . memoryCache . get ( redisKey ) ;
937- if ( inMemoryValue ) {
938- const renewedAgo = ( new Date ( ) ) . getTime ( ) - inMemoryValue . time ;
939-
940- if (
941- renewalKey && (
942- ! renewalThreshold ||
943- ! inMemoryValue . time ||
944- // Do not cache in memory in last 5 minutes of expiry.
945- // Most likely it'll cause race condition of refreshing data with different refreshKey values.
946- renewedAgo + inMemoryCacheDisablePeriod > renewalThreshold * 1000 ||
947- inMemoryValue . renewalKey !== renewalKey
948- ) || renewedAgo > expiration * 1000 || renewedAgo > inMemoryCacheDisablePeriod
949- ) {
950- this . memoryCache . delete ( redisKey ) ;
951- } else {
952- this . logger ( 'Found in memory cache entry' , {
953- cacheKey,
954- time : inMemoryValue . time ,
955- renewedAgo,
956- renewalKey : inMemoryValue . renewalKey ,
957- newRenewalKey : renewalKey ,
958- renewalThreshold,
959- requestId : options . requestId ,
960- spanId,
961- primaryQuery,
962- renewCycle
963- } ) ;
964- res = inMemoryValue ;
965- }
1002+ const cachedResult = await this . checkInCache (
1003+ redisKey ,
1004+ {
1005+ renewalKey,
1006+ renewalThreshold,
1007+ expiration,
1008+ options,
1009+ spanId,
1010+ cacheKey,
1011+ primaryQuery,
1012+ renewCycle
9661013 }
967- }
968-
969- if ( ! res ) {
970- res = await this . cacheDriver . get ( redisKey ) ;
971- }
1014+ ) ;
9721015
973- if ( res ) {
974- const parsedResult = res ;
975- const renewedAgo = ( new Date ( ) ) . getTime ( ) - parsedResult . time ;
1016+ if ( cachedResult ) {
1017+ const renewedAgo = ( new Date ( ) ) . getTime ( ) - cachedResult . time ;
9761018 this . logger ( 'Found cache entry' , {
9771019 cacheKey,
978- time : parsedResult . time ,
1020+ time : cachedResult . time ,
9791021 renewedAgo,
980- renewalKey : parsedResult . renewalKey ,
1022+ renewalKey : cachedResult . renewalKey ,
9811023 newRenewalKey : renewalKey ,
9821024 renewalThreshold,
9831025 requestId : options . requestId ,
@@ -988,9 +1030,9 @@ export class QueryCache {
9881030 if (
9891031 renewalKey && (
9901032 ! renewalThreshold ||
991- ! parsedResult . time ||
1033+ ! cachedResult . time ||
9921034 renewedAgo > renewalThreshold * 1000 ||
993- parsedResult . renewalKey !== renewalKey
1035+ cachedResult . renewalKey !== renewalKey
9941036 )
9951037 ) {
9961038 if ( options . waitForRenew ) {
@@ -1008,11 +1050,12 @@ export class QueryCache {
10081050
10091051 this . logger ( 'Using cache for' , { cacheKey, requestId : options . requestId , spanId, primaryQuery, renewCycle } ) ;
10101052
1053+ const inMemoryCacheDisablePeriod = 5 * 60 * 1000 ;
10111054 if ( options . useInMemory && renewedAgo + inMemoryCacheDisablePeriod <= renewalThreshold * 1000 ) {
1012- this . memoryCache . set ( redisKey , parsedResult ) ;
1055+ this . memoryCache . set ( redisKey , cachedResult ) ;
10131056 }
10141057
1015- return parsedResult . result ;
1058+ return cachedResult . result ;
10161059 } else {
10171060 this . logger ( 'Missing cache for' , { cacheKey, requestId : options . requestId , spanId, primaryQuery, renewCycle } ) ;
10181061 return fetchNew ( ) ;
0 commit comments