in edge-agent/src/Microsoft.Azure.Devices.Edge.Agent.Core/planrunner/OrdererdRetryPlanRunner.cs [38:132]
public async Task<bool> ExecuteAsync(long deploymentId, Plan plan, CancellationToken token)
{
Preconditions.CheckRange(deploymentId, -1, nameof(deploymentId));
Preconditions.CheckNotNull(plan, nameof(plan));
using (await this.sync.LockAsync())
{
Events.PlanExecStarted(deploymentId);
// if this is a new deployment we haven't seen before then clear the
// saved command run status values
if (this.lastDeploymentId != -1 && this.lastDeploymentId != deploymentId)
{
Events.NewDeployment(deploymentId);
this.commandRunStatus.Clear();
}
else
{
if (this.lastDeploymentId != -1)
{
Events.OldDeployment(deploymentId);
}
else
{
Events.NewDeployment(deploymentId);
}
}
// update saved deployment ID
this.lastDeploymentId = deploymentId;
Option<List<Exception>> failures = Option.None<List<Exception>>();
bool skippedModules = false;
foreach (ICommand command in plan.Commands)
{
(bool shouldRun, int runCount, TimeSpan coolOffPeriod, TimeSpan elapsedTime) = this.ShouldRunCommand(command);
if (this.ShouldSkipRemaining(shouldRun, command))
{
Events.SkipRemainingCommands(deploymentId, command);
break;
}
try
{
if (token.IsCancellationRequested)
{
Events.PlanExecCancelled(deploymentId);
skippedModules = true;
break;
}
if (shouldRun)
{
await command.ExecuteAsync(token);
// since this command ran successfully reset its
// run status
if (this.commandRunStatus.ContainsKey(command.Id))
{
this.commandRunStatus[command.Id] = CommandRunStats.Default;
}
}
else
{
skippedModules = true;
Events.SkippingCommand(deploymentId, command, this.commandRunStatus[command.Id], this.maxRunCount, coolOffPeriod, elapsedTime);
}
}
catch (Exception ex) when (ex.IsFatal() == false)
{
Events.PlanExecStepFailed(deploymentId, command, coolOffPeriod, elapsedTime);
if (!failures.HasValue)
{
failures = Option.Some(new List<Exception>());
}
failures.ForEach(f => f.Add(ex));
// since this command failed, record its status
int newRunCount = this.commandRunStatus.ContainsKey(command.Id) ? this.commandRunStatus[command.Id].RunCount : 0;
this.commandRunStatus[command.Id] = new CommandRunStats(newRunCount + 1, this.systemTime.UtcNow, ex);
if (ex is ExecutionPrerequisiteException)
{
Events.StopProcessingCommands(deploymentId, command);
break;
}
}
}
Events.PlanExecEnded(deploymentId);
failures.ForEach(f => throw new AggregateException(f));
return !skippedModules;
}
}