@@ -225,6 +225,10 @@ export async function queryMembersAdvanced(
225225 const cachedCount = countOnly ? await cache . getCount ( countCacheKey ) : null
226226
227227 if ( cachedResult ) {
228+ log . info (
229+ { cacheKey, segmentId, search : normalizedSearch , limit, offset, orderBy } ,
230+ 'Members advanced query cache hit — returning cached result, scheduling background refresh' ,
231+ )
228232 refreshCacheInBackground ( bgQx , redis , cacheKey , {
229233 filter,
230234 search : normalizedSearch ,
@@ -238,12 +242,14 @@ export async function queryMembersAdvanced(
238242 includeAllAttributes,
239243 attributeSettings,
240244 } )
241-
242- log . info ( `Members advanced query cache hit: ${ cacheKey } ` )
243245 return cachedResult
244246 }
245247
246248 if ( countOnly && cachedCount !== null ) {
249+ log . info (
250+ { countCacheKey, segmentId, search : normalizedSearch } ,
251+ 'Members advanced count cache hit — returning cached count, scheduling background refresh' ,
252+ )
247253 refreshCountCacheInBackground ( bgQx , redis , countCacheKey , {
248254 filter,
249255 search : normalizedSearch ,
@@ -252,8 +258,6 @@ export async function queryMembersAdvanced(
252258 includeAllAttributes,
253259 attributeSettings,
254260 } )
255-
256- log . debug ( `Members advanced count query cache hit: ${ countCacheKey } ` )
257261 return {
258262 rows : [ ] ,
259263 count : cachedCount ,
@@ -262,19 +266,65 @@ export async function queryMembersAdvanced(
262266 }
263267 }
264268
265- return await executeQuery ( qx , redis , cacheKey , {
266- filter,
267- search : normalizedSearch ,
268- limit,
269- offset,
270- orderBy,
271- segmentId,
272- countOnly,
273- fields,
274- include,
275- includeAllAttributes,
276- attributeSettings,
277- } )
269+ log . info (
270+ {
271+ cacheKey,
272+ countCacheKey,
273+ segmentId,
274+ search : normalizedSearch ,
275+ limit,
276+ offset,
277+ orderBy,
278+ countOnly,
279+ } ,
280+ 'Members advanced query cache miss — executing query synchronously' ,
281+ )
282+
283+ try {
284+ return await executeQuery ( qx , redis , cacheKey , {
285+ filter,
286+ search : normalizedSearch ,
287+ limit,
288+ offset,
289+ orderBy,
290+ segmentId,
291+ countOnly,
292+ fields,
293+ include,
294+ includeAllAttributes,
295+ attributeSettings,
296+ } )
297+ } catch ( error ) {
298+ log . warn (
299+ { cacheKey, countCacheKey, segmentId, search : normalizedSearch , countOnly, err : error } ,
300+ 'Members advanced query failed on cache miss — scheduling background refresh for next retry' ,
301+ )
302+ if ( countOnly ) {
303+ refreshCountCacheInBackground ( bgQx , redis , countCacheKey , {
304+ filter,
305+ search : normalizedSearch ,
306+ segmentId,
307+ include,
308+ includeAllAttributes,
309+ attributeSettings,
310+ } )
311+ } else {
312+ refreshCacheInBackground ( bgQx , redis , cacheKey , {
313+ filter,
314+ search : normalizedSearch ,
315+ limit,
316+ offset,
317+ orderBy,
318+ segmentId,
319+ countOnly : false ,
320+ fields,
321+ include,
322+ includeAllAttributes,
323+ attributeSettings,
324+ } )
325+ }
326+ throw error
327+ }
278328}
279329
280330export async function executeQuery (
@@ -567,29 +617,36 @@ async function refreshCacheInBackground(
567617 redis : RedisClient ,
568618 cacheKey : string ,
569619 params : IQueryMembersAdvancedParams ,
620+ countOnly = false ,
570621) : Promise < void > {
622+ const label = countOnly ? 'count cache' : 'query cache'
623+ const cache = new MemberQueryCache ( redis )
624+ const acquired = await cache . tryAcquireRefreshLock ( cacheKey )
625+ if ( ! acquired ) {
626+ log . debug (
627+ { cacheKey } ,
628+ `Members advanced ${ label } refresh already in progress — skipping duplicate` ,
629+ )
630+ return
631+ }
571632 try {
572- log . info ( `Refreshing members advanced query cache in background: ${ cacheKey } `)
573- await executeQuery ( qx , redis , cacheKey , params )
574- log . info ( `Members advanced query cache refreshed in background: ${ cacheKey } ` )
633+ log . info ( { cacheKey } , `Members advanced ${ label } background refresh started `)
634+ await executeQuery ( qx , redis , cacheKey , countOnly ? { ... params , countOnly : true } : params )
635+ log . info ( { cacheKey } , `Members advanced ${ label } background refresh completed ` )
575636 } catch ( error ) {
576- log . warn ( 'Background cache refresh failed:' , error )
637+ log . warn ( { cacheKey, err : error } , `Members advanced ${ label } background refresh failed` )
638+ } finally {
639+ await cache . releaseRefreshLock ( cacheKey )
577640 }
578641}
579642
580- async function refreshCountCacheInBackground (
643+ function refreshCountCacheInBackground (
581644 qx : QueryExecutor ,
582645 redis : RedisClient ,
583646 cacheKey : string ,
584647 params : IQueryMembersAdvancedParams ,
585648) : Promise < void > {
586- try {
587- log . info ( `Refreshing members advanced count cache in background: ${ cacheKey } ` )
588- await executeQuery ( qx , redis , cacheKey , { ...params , countOnly : true } )
589- log . info ( `Members advanced count cache refreshed in background: ${ cacheKey } ` )
590- } catch ( error ) {
591- log . warn ( 'Background count cache refresh failed:' , error )
592- }
649+ return refreshCacheInBackground ( qx , redis , cacheKey , params , true )
593650}
594651
595652export async function queryMembers < T extends MemberField > (
0 commit comments