@@ -20,7 +20,7 @@ function isPreconditionFailedError(error: unknown): boolean {
2020
2121const depthProbeConcurrency = 8 ;
2222const delayedQueueExpiryMargin = 60_000 ;
23- const delayedQueueTrackingLimit = 4096 ;
23+ const delayedQueueCleanupThreshold = 4096 ;
2424
2525/**
2626 * Options for ordering key support in {@link AmqpMessageQueue}.
@@ -143,6 +143,7 @@ export class AmqpMessageQueue implements MessageQueue {
143143 partitions : number ;
144144 } ;
145145 #delayedQueues: Set < string > = new Set ( ) ;
146+ #delayedQueueCleanup?: Promise < void > ;
146147 #orderingPrepared: boolean = false ;
147148
148149 readonly nativeRetrial : boolean ;
@@ -384,10 +385,15 @@ export class AmqpMessageQueue implements MessageQueue {
384385
385386 #trackDelayedQueue( queue : string ) : void {
386387 this . #delayedQueues. add ( queue ) ;
387- while ( this . #delayedQueues. size > delayedQueueTrackingLimit ) {
388- const oldestQueue = this . #delayedQueues. values ( ) . next ( ) . value ;
389- if ( oldestQueue == null ) break ;
390- this . #delayedQueues. delete ( oldestQueue ) ;
388+ if (
389+ this . #delayedQueues. size > delayedQueueCleanupThreshold &&
390+ this . #delayedQueueCleanup == null
391+ ) {
392+ this . #delayedQueueCleanup = this . #pruneMissingDelayedQueues( )
393+ . catch ( ( ) => undefined )
394+ . finally ( ( ) => {
395+ this . #delayedQueueCleanup = undefined ;
396+ } ) ;
391397 }
392398 }
393399
@@ -429,24 +435,6 @@ export class AmqpMessageQueue implements MessageQueue {
429435 return channel ;
430436 }
431437
432- async #checkQueueDepth( queueName : string ) : Promise < number | undefined > {
433- const channel = await this . #createDepthChannel( ) ;
434- try {
435- return ( await channel . checkQueue ( queueName ) ) . messageCount ;
436- } catch ( error ) {
437- if ( ! isQueueNotFoundError ( error ) ) {
438- throw error ;
439- }
440- return undefined ;
441- } finally {
442- try {
443- await channel . close ( ) ;
444- } catch {
445- // The channel can already be closed by a failed passive queue check.
446- }
447- }
448- }
449-
450438 async #checkQueueDepths(
451439 queueNames : readonly string [ ] ,
452440 ) : Promise < readonly ( readonly [ string , number | undefined ] ) [ ] > {
@@ -455,10 +443,37 @@ export class AmqpMessageQueue implements MessageQueue {
455443 ) ;
456444 let nextIndex = 0 ;
457445 const worker = async ( ) => {
458- while ( nextIndex < queueNames . length ) {
459- const index = nextIndex ++ ;
460- const queue = queueNames [ index ] ;
461- results [ index ] = [ queue , await this . #checkQueueDepth( queue ) ] ;
446+ let channel : Channel | undefined ;
447+ const closeChannel = async ( ) => {
448+ if ( channel == null ) return ;
449+ const currentChannel = channel ;
450+ channel = undefined ;
451+ try {
452+ await currentChannel . close ( ) ;
453+ } catch {
454+ // The channel can already be closed by a failed passive queue check.
455+ }
456+ } ;
457+ const checkQueue = async (
458+ queue : string ,
459+ ) : Promise < number | undefined > => {
460+ channel ??= await this . #createDepthChannel( ) ;
461+ try {
462+ return ( await channel . checkQueue ( queue ) ) . messageCount ;
463+ } catch ( error ) {
464+ await closeChannel ( ) ;
465+ if ( ! isQueueNotFoundError ( error ) ) throw error ;
466+ return undefined ;
467+ }
468+ } ;
469+ try {
470+ while ( nextIndex < queueNames . length ) {
471+ const index = nextIndex ++ ;
472+ const queue = queueNames [ index ] ;
473+ results [ index ] = [ queue , await checkQueue ( queue ) ] ;
474+ }
475+ } finally {
476+ await closeChannel ( ) ;
462477 }
463478 } ;
464479 const workers = Array . from (
@@ -469,6 +484,15 @@ export class AmqpMessageQueue implements MessageQueue {
469484 return results ;
470485 }
471486
487+ async #pruneMissingDelayedQueues( ) : Promise < void > {
488+ const delayedQueues = [ ...this . #delayedQueues] ;
489+ for (
490+ const [ queue , messageCount ] of await this . #checkQueueDepths( delayedQueues )
491+ ) {
492+ if ( messageCount == null ) this . #delayedQueues. delete ( queue ) ;
493+ }
494+ }
495+
472496 async getDepth ( ) : Promise < MessageQueueDepth > {
473497 const readyQueues = [ this . #queue] ;
474498 if ( this . #ordering != null ) {
0 commit comments