@@ -452,7 +452,7 @@ class ThreadPool {
452452 this . histogram ?. recordWaitTime ( now - task . created )
453453 task . started = now ;
454454 candidate [ kWorkerData ] . postTask ( task ) ;
455- queueMicrotask ( ( ) => this . _maybeDrain ( ) ) ;
455+ this . _maybeDrain ( ) ;
456456 // If candidate, let's try to distribute more tasks
457457 return true ;
458458 }
@@ -515,7 +515,7 @@ class ThreadPool {
515515 resolve ( result ) ;
516516 }
517517
518- queueMicrotask ( this . _maybeDrain . bind ( this ) )
518+ this . _maybeDrain ( ) ;
519519 } ) ;
520520
521521 if ( signal != null ) {
@@ -558,7 +558,7 @@ class ThreadPool {
558558 this . taskQueue . push ( taskInfo ) ;
559559 }
560560
561- queueMicrotask ( this . _maybeDrain . bind ( this ) )
561+ this . _maybeDrain ( ) ;
562562 return ret ;
563563 }
564564
@@ -578,7 +578,7 @@ class ThreadPool {
578578 }
579579 } ;
580580
581- queueMicrotask ( this . _maybeDrain . bind ( this ) )
581+ this . _maybeDrain ( ) ;
582582 return ret ;
583583 }
584584
@@ -594,16 +594,26 @@ class ThreadPool {
594594 * since we want to avoid creating tasks that can't execute
595595 * immediately in order to provide back pressure to the task source.
596596 */
597- const { maxCapacity } = this ;
597+ const { maxCapacity, } = this ;
598598 const currentUsage = this . workers . getCurrentUsage ( ) ;
599+ const maxQueueSize = this . options . maxQueue ;
600+ const queueSize = this . publicInterface . queueSize ;
599601
600- if ( maxCapacity === currentUsage ) {
602+ if ( this . _needsDrain === true ) {
603+ if ( queueSize === 0 ) {
604+ this . _needsDrain = false ;
605+ queueMicrotask ( ( ) => this . publicInterface . emit ( 'drain' ) ) ;
606+ }
607+ return ;
608+ }
609+
610+ // Attempting to provide a similar behaviour to a Writable stream
611+ // if maxquesize is already reached, let's attempt to inform that the
612+ // queue needs drain before handling more tasks
613+ if ( maxCapacity === currentUsage && queueSize === maxQueueSize ) {
601614 this . _needsDrain = true ;
602615 queueMicrotask ( ( ) => this . publicInterface . emit ( 'needsDrain' ) ) ;
603- } else if ( maxCapacity > currentUsage && this . _needsDrain ) {
604- this . _needsDrain = false ;
605- queueMicrotask ( ( ) => this . publicInterface . emit ( 'drain' ) ) ;
606- }
616+ }
607617 }
608618
609619 async destroy ( ) {
@@ -853,7 +863,7 @@ export default class Piscina<Exports extends Record<string, (payload: any) => an
853863
854864 get queueSize ( ) : number {
855865 const pool = this . #pool;
856- return Math . max ( pool . taskQueue . size - pool . pendingCapacity ( ) , 0 ) ;
866+ return Math . max ( ( pool . taskQueue . size + pool . skipQueue . length ) - pool . pendingCapacity ( ) , 0 ) ;
857867 }
858868
859869 get completed ( ) : number {
0 commit comments