Пример #1
0
 public Agent(
     IConfigSource configSource,
     IEnvironmentProvider environmentProvider,
     IPlanner planner,
     IPlanRunner planRunner,
     IReporter reporter,
     IModuleIdentityLifecycleManager moduleIdentityLifecycleManager,
     IEntityStore <string, string> configStore,
     DeploymentConfigInfo initialDeployedConfigInfo,
     ISerde <DeploymentConfigInfo> deploymentConfigInfoSerde,
     IEncryptionProvider encryptionProvider,
     IAvailabilityMetric availabilityMetric)
 {
     this.configSource = Preconditions.CheckNotNull(configSource, nameof(configSource));
     this.planner      = Preconditions.CheckNotNull(planner, nameof(planner));
     this.planRunner   = Preconditions.CheckNotNull(planRunner, nameof(planRunner));
     this.reporter     = Preconditions.CheckNotNull(reporter, nameof(reporter));
     this.moduleIdentityLifecycleManager = Preconditions.CheckNotNull(moduleIdentityLifecycleManager, nameof(moduleIdentityLifecycleManager));
     this.configStore               = Preconditions.CheckNotNull(configStore, nameof(configStore));
     this.environmentProvider       = Preconditions.CheckNotNull(environmentProvider, nameof(environmentProvider));
     this.currentConfig             = Preconditions.CheckNotNull(initialDeployedConfigInfo);
     this.deploymentConfigInfoSerde = Preconditions.CheckNotNull(deploymentConfigInfoSerde, nameof(deploymentConfigInfoSerde));
     this.environment               = this.environmentProvider.Create(this.currentConfig.DeploymentConfig);
     this.encryptionProvider        = Preconditions.CheckNotNull(encryptionProvider, nameof(encryptionProvider));
     this.availabilityMetric        = Preconditions.CheckNotNull(availabilityMetric, nameof(availabilityMetric));
     this.status = DeploymentStatus.Unknown;
     Events.AgentCreated();
 }
Пример #2
0
 internal async Task ReportShutdownAsync(CancellationToken token)
 {
     try
     {
         var status = new DeploymentStatus(DeploymentStatusCode.Unknown, "Agent is not running");
         await this.reporter.ReportShutdown(status, token);
         Events.ReportShutdown();
     }
     catch (Exception ex) when (!ex.IsFatal())
     {
         Events.ReportShutdownFailed(ex);
     }
 }
Пример #3
0
 public async Task HandleShutdown(CancellationToken token)
 {
     try
     {
         Events.InitiateShutdown();
         Task shutdownModulesTask = this.ShutdownModules(token);
         var status = new DeploymentStatus(DeploymentStatusCode.Unknown, "Agent is not running");
         Task reportShutdownTask = this.reporter.ReportShutdown(status, token);
         await Task.WhenAll(shutdownModulesTask, reportShutdownTask);
         Events.CompletedShutdown();
     }
     catch (Exception ex) when (!ex.IsFatal())
     {
         Events.HandleShutdownFailed(ex);
     }
 }
Пример #4
0
        public async Task ReconcileAsync(CancellationToken token)
        {
            ModuleSet moduleSetToReport = null;

            using (await this.reconcileLock.LockAsync(token))
            {
                try
                {
                    Events.StartingReconcile();
                    (ModuleSet current, DeploymentConfigInfo deploymentConfigInfo, Exception exception) = await this.GetReconcileData(token);

                    moduleSetToReport = current;
                    if (exception != null)
                    {
                        ExceptionDispatchInfo.Capture(exception).Throw();
                    }

                    DeploymentConfig deploymentConfig = deploymentConfigInfo.DeploymentConfig;
                    if (deploymentConfig.Equals(DeploymentConfig.Empty))
                    {
                        this.status = DeploymentStatus.Success;
                    }
                    else
                    {
                        ModuleSet desiredModuleSet = deploymentConfig.GetModuleSet();
                        _ = Task.Run(() => this.availabilityMetric.ComputeAvailability(desiredModuleSet, current))
                            .ContinueWith(t => Events.UnknownFailure(t.Exception), TaskContinuationOptions.OnlyOnFaulted)
                            .ConfigureAwait(false);

                        // TODO - Update this logic to create identities only when needed, in the Command factory, instead of creating all the identities
                        // up front here. That will allow handling the case when only the state of the system has changed (say one module crashes), and
                        // no new identities need to be created. This will simplify the logic to allow EdgeAgent to work when offline.
                        // But that required ModuleSet.Diff to be updated to include modules updated by deployment, and modules updated by state change.
                        IImmutableDictionary <string, IModuleIdentity> identities = await this.moduleIdentityLifecycleManager.GetModuleIdentitiesAsync(desiredModuleSet, current);

                        Plan plan = await this.planner.PlanAsync(desiredModuleSet, current, deploymentConfig.Runtime, identities);

                        if (plan.IsEmpty)
                        {
                            this.status = DeploymentStatus.Success;
                        }
                        else
                        {
                            try
                            {
                                bool result = await this.planRunner.ExecuteAsync(deploymentConfigInfo.Version, plan, token);

                                await this.UpdateCurrentConfig(deploymentConfigInfo);

                                if (result)
                                {
                                    this.status = DeploymentStatus.Success;
                                }
                            }
                            catch (Exception ex) when(!ex.IsFatal())
                            {
                                Events.PlanExecutionFailed(ex);
                                await this.UpdateCurrentConfig(deploymentConfigInfo);

                                throw;
                            }
                        }
                    }
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    switch (ex)
                    {
                    case ConfigEmptyException _:
                        this.status = new DeploymentStatus(DeploymentStatusCode.ConfigEmptyError, ex.Message);
                        Events.EmptyConfig(ex);
                        break;

                    case InvalidSchemaVersionException _:
                        this.status = new DeploymentStatus(DeploymentStatusCode.InvalidSchemaVersion, ex.Message);
                        Events.InvalidSchemaVersion(ex);
                        break;

                    case ConfigFormatException _:
                        this.status = new DeploymentStatus(DeploymentStatusCode.ConfigFormatError, ex.Message);
                        Events.InvalidConfigFormat(ex);
                        break;

                    default:
                        this.status = new DeploymentStatus(DeploymentStatusCode.Failed, ex.Message);
                        Events.UnknownFailure(ex);
                        break;
                    }
                }

                await this.reporter.ReportAsync(token, moduleSetToReport, await this.environment.GetRuntimeInfoAsync(), this.currentConfig.Version, this.status);

                Events.FinishedReconcile();
            }
        }