public async Task ExecuteAsync()

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;
            }
        }