@@ -296,6 +296,14 @@ export abstract class AbstractPool<
296296 : accumulator ,
297297 0 ,
298298 ) ,
299+ ...( this . opts . enableTasksQueue === true &&
300+ {
301+ stealingWorkerNodes : this . workerNodes . reduce (
302+ ( accumulator , workerNode ) =>
303+ workerNode . info . stealing ? accumulator + 1 : accumulator ,
304+ 0 ,
305+ ) ,
306+ } ) ,
299307 busyWorkerNodes : this . workerNodes . reduce (
300308 ( accumulator , _workerNode , workerNodeKey ) =>
301309 this . isWorkerNodeBusy ( workerNodeKey ) ? accumulator + 1 : accumulator ,
@@ -1375,6 +1383,10 @@ export abstract class AbstractPool<
13751383 } )
13761384 }
13771385
1386+ private cannotStealTask ( ) : boolean {
1387+ return this . workerNodes . length <= 1 || this . info . queuedTasks === 0
1388+ }
1389+
13781390 private handleTask ( workerNodeKey : number , task : Task < Data > ) : void {
13791391 if ( this . shallExecuteTask ( workerNodeKey ) ) {
13801392 this . executeTask ( workerNodeKey , task )
@@ -1387,7 +1399,7 @@ export abstract class AbstractPool<
13871399 if ( workerNodeKey === - 1 ) {
13881400 return
13891401 }
1390- if ( this . workerNodes . length <= 1 ) {
1402+ if ( this . cannotStealTask ( ) ) {
13911403 return
13921404 }
13931405 while ( this . tasksQueueSize ( workerNodeKey ) > 0 ) {
@@ -1481,22 +1493,29 @@ export abstract class AbstractPool<
14811493 event : CustomEvent < WorkerNodeEventDetail > ,
14821494 previousStolenTask ?: Task < Data > ,
14831495 ) : void => {
1484- if ( this . workerNodes . length <= 1 ) {
1485- return
1486- }
14871496 const { workerNodeKey } = event . detail
14881497 if ( workerNodeKey == null ) {
14891498 throw new Error (
1490- 'WorkerNode event detail workerNodeKey attribute must be defined' ,
1499+ 'WorkerNode event detail workerNodeKey property must be defined' ,
14911500 )
14921501 }
1502+ if (
1503+ this . cannotStealTask ( ) || ( this . info . stealingWorkerNodes as number ) >
1504+ Math . floor ( this . workerNodes . length / 2 )
1505+ ) {
1506+ if ( previousStolenTask != null ) {
1507+ this . getWorkerInfo ( workerNodeKey ) . stealing = false
1508+ }
1509+ return
1510+ }
14931511 const workerNodeTasksUsage = this . workerNodes [ workerNodeKey ] . usage . tasks
14941512 if (
14951513 previousStolenTask != null &&
14961514 workerNodeTasksUsage . sequentiallyStolen > 0 &&
14971515 ( workerNodeTasksUsage . executing > 0 ||
14981516 this . tasksQueueSize ( workerNodeKey ) > 0 )
14991517 ) {
1518+ this . getWorkerInfo ( workerNodeKey ) . stealing = false
15001519 for (
15011520 const taskName of this . workerNodes [ workerNodeKey ] . info
15021521 . taskFunctionNames as string [ ]
@@ -1511,6 +1530,7 @@ export abstract class AbstractPool<
15111530 )
15121531 return
15131532 }
1533+ this . getWorkerInfo ( workerNodeKey ) . stealing = true
15141534 const stolenTask = this . workerNodeStealTask ( workerNodeKey )
15151535 if (
15161536 this . shallUpdateTaskFunctionWorkerUsage ( workerNodeKey ) &&
@@ -1556,6 +1576,7 @@ export abstract class AbstractPool<
15561576 const sourceWorkerNode = workerNodes . find (
15571577 ( sourceWorkerNode , sourceWorkerNodeKey ) =>
15581578 sourceWorkerNode . info . ready &&
1579+ ! sourceWorkerNode . info . stealing &&
15591580 sourceWorkerNodeKey !== workerNodeKey &&
15601581 sourceWorkerNode . usage . tasks . queued > 0 ,
15611582 )
@@ -1576,7 +1597,10 @@ export abstract class AbstractPool<
15761597 private readonly handleBackPressureEvent = (
15771598 event : CustomEvent < WorkerNodeEventDetail > ,
15781599 ) : void => {
1579- if ( this . workerNodes . length <= 1 ) {
1600+ if (
1601+ this . cannotStealTask ( ) || ( this . info . stealingWorkerNodes as number ) >
1602+ Math . floor ( this . workerNodes . length / 2 )
1603+ ) {
15801604 return
15811605 }
15821606 const { workerId } = event . detail
@@ -1596,16 +1620,19 @@ export abstract class AbstractPool<
15961620 if (
15971621 sourceWorkerNode . usage . tasks . queued > 0 &&
15981622 workerNode . info . ready &&
1623+ ! workerNode . info . stealing &&
15991624 workerNode . info . id !== workerId &&
16001625 workerNode . usage . tasks . queued <
16011626 ( this . opts . tasksQueueOptions ?. size as number ) - sizeOffset
16021627 ) {
1628+ this . getWorkerInfo ( workerNodeKey ) . stealing = true
16031629 const task = sourceWorkerNode . popTask ( ) as Task < Data >
16041630 this . handleTask ( workerNodeKey , task )
16051631 this . updateTaskStolenStatisticsWorkerUsage (
16061632 workerNodeKey ,
16071633 task . name as string ,
16081634 )
1635+ this . getWorkerInfo ( workerNodeKey ) . stealing = false
16091636 }
16101637 }
16111638 }
0 commit comments