title: Release Management vNext Component Deployment Bottleneck
body: <p>We're using Release Management 2015 with vNext release templates. We have a Powershell DSC based component deployment for each of the portions of our application, and in fact, we have two distinct applications being deployed and that are in active development and are often deployed at nearly the same time.</p>
  
  <p>We very frequently get the following error during deployments:</p>
  
  <blockquote>
    <p>OperationFailedException: New deployment is not allowed as an another deployment is in progress. Retry the deployment after sometime.</p>
  </blockquote>
  
  <p>The full stack trace shows that the error is coming not from Powershell itself, but from Release Management's system that's in charge of execution of the powershell script on the target machine:</p>
  
  <pre><code>System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---&gt; Microsoft.TeamFoundation.Release.Common.Helpers.OperationFailedException: New deployment is not allowed as an another deployment is in progress. Retry the deployment after sometime.
     at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.ReadDeploymentResponse(DeploymentResponse response)
     at Microsoft.TeamFoundation.Release.EnvironmentProvider.OnPrem.Implementation.OnPremDeploymentProvider.RunScript(String scriptPath, String configurationPath, MachineSpecification machine, StorageSpecification storage, Dictionary`2 configurationVariables)
     at Microsoft.TeamFoundation.Release.MonitorServices.Dsc.OnPrem.OnPremDeploymentActions.InvokePlatform(String activityId, MachineSpecification machineSpecification, StorageSpecification storageSpecification, String scriptPath, String configurationPath, Dictionary`2 configurationVariables)
     --- End of inner exception stack trace ---
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
     at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
     at Microsoft.TeamFoundation.Release.DeploymentAgent.Services.Deployer.Dsc.DscComponentInstaller.InvokeMethodByReflection(String methodArguments)
  </code></pre>
  
  <p>The above error causes the entire deployment to fail, and we're forced to retry the stage or the entire deployment to have it finish.</p>
  
  <p>There are two scenarios that cause this:</p>
  
  <ol>
  <li>Two release templates execute their powershell scripts on the same target server at the same time</li>
  <li>A single release template has a parallel control flow which contains two different components that both execute scripts on the same target server</li>
  </ol>
  
  <p>In other words, the mechanism that Release Management uses to execute a powershell script on a remote server can only seem to ever execute a single script at a time, and has no ability to wait/hold for others to complete.</p>
  
  <p>This kinda/sorta makes sense if the script in question as actively modifying the server on which it's executing, but in our case, the server acts as basically a staging area to run the script. The "real" target of the script has nothing to do with the server on which the powershell happens to be executing.</p>
  
  <p>Aside from having a server-per-simultaneously-deployed-component (wow), what's the work around here? It seems like a major oversight and it's seriously making me consider dropping Release Management altogether.</p>