1- using  Microsoft . Azure . Functions . Worker ; 
1+ using  System . Threading . Tasks ; 
2+ using  Microsoft . Azure . Functions . Worker ; 
23using  Microsoft . Extensions . Logging ; 
34namespace  Microsoft . OneFuzz . Service . Functions ; 
45
@@ -43,16 +44,17 @@ public async Async.Task Run([TimerTrigger("00:01:30")] TimerInfo t) {
4344        // (such as shutdown or resize) happen during this iteration `timer_worker` 
4445        // rather than the following iteration. 
4546
46-         var  pools  =  _poolOps . SearchStates ( states :  PoolStateHelper . NeedsWork ) ; 
47-         await  foreach  ( var  pool  in  pools )  { 
47+         // we do not expect there to be many pools that need work, process them all in parallel 
48+         var  pools  =  await  _poolOps . SearchStates ( states :  PoolStateHelper . NeedsWork ) . ToListAsync ( ) ; 
49+         await  Async . Task . WhenAll ( pools . Select ( async  pool =>  { 
4850            try  { 
4951                _log . LogInformation ( "updating pool: {PoolId} ({PoolName}) - state: {PoolState}" ,  pool . PoolId ,  pool . Name ,  pool . State ) ; 
5052                var  newPool  =  await  _poolOps . ProcessStateUpdate ( pool ) ; 
5153                _log . LogInformation ( "completed updating pool: {PoolId} ({PoolName}) - now in state {PoolState}" ,  pool . PoolId ,  pool . Name ,  newPool . State ) ; 
5254            }  catch  ( Exception  ex )  { 
5355                _log . LogError ( ex ,  "failed to process pool" ) ; 
5456            } 
55-         } 
57+         } ) ) ; 
5658
5759        // NOTE: Nodes, and Scalesets should be processed in a consistent order such 
5860        // during 'pool scale down' operations. This means that pools that are 
@@ -63,26 +65,29 @@ public async Async.Task Run([TimerTrigger("00:01:30")] TimerInfo t) {
6365        await  _nodeOps . MarkOutdatedNodes ( ) ; 
6466        await  _nodeOps . CleanupBusyNodesWithoutWork ( ) ; 
6567
68+         // process up to 10 nodes in parallel 
6669        var  nodes  =  _nodeOps . SearchStates ( states :  NodeStateHelper . NeedsWorkStates ) ; 
67-         await  foreach  ( var  node  in  nodes )  { 
70+         var  parallelOptions  =  new  ParallelOptions  {  MaxDegreeOfParallelism  =  10  } ; 
71+         await  Parallel . ForEachAsync ( nodes ,  parallelOptions ,  async  ( node ,  _cancel )  =>  { 
6872            try  { 
6973                _log . LogInformation ( "updating node: {MachineId} - state: {NodeState}" ,  node . MachineId ,  node . State ) ; 
7074                var  newNode  =  await  _nodeOps . ProcessStateUpdate ( node ) ; 
7175                _log . LogInformation ( "completed updating node: {MachineId} - now in state {NodeState}" ,  node . MachineId ,  newNode . State ) ; 
7276            }  catch  ( Exception  ex )  { 
7377                _log . LogError ( ex ,  "failed to process node" ) ; 
7478            } 
75-         } 
79+         } ) ; 
7680
77-         var  scalesets  =  _scaleSetOps . SearchAll ( ) ; 
78-         await  foreach  ( var  scaleset  in  scalesets )  { 
81+         // we do not expect there to be many scalesets, process them all in parallel 
82+         var  scalesets  =  await  _scaleSetOps . SearchAll ( ) . ToListAsync ( ) ; 
83+         await  Async . Task . WhenAll ( scalesets . Select ( async  scaleset =>  { 
7984            try  { 
8085                _log . LogInformation ( "updating scaleset: {ScalesetId} - state: {ScalesetState}" ,  scaleset . ScalesetId ,  scaleset . State ) ; 
8186                var  newScaleset  =  await  ProcessScalesets ( scaleset ) ; 
8287                _log . LogInformation ( "completed updating scaleset: {ScalesetId} - now in state {ScalesetState}" ,  scaleset . ScalesetId ,  newScaleset . State ) ; 
8388            }  catch  ( Exception  ex )  { 
8489                _log . LogError ( ex ,  "failed to process scaleset" ) ; 
8590            } 
86-         } 
91+         } ) ) ; 
8792    } 
8893} 
0 commit comments