예제 #1
0
        internal void StartConfigUpdateDeliveryToAppInstanceMgr(AppInstanceManager appInstanceMgr)
        {
            this.appInstanceMgr = appInstanceMgr;
            bool result = this.windowsFabricApplicationCreated.Set();

            if (false == result)
            {
                Utility.TraceSource.WriteError(
                    TraceType,
                    "Error setting event to indicate that config updates can be delivered to app instance manager.");
            }

            Utility.TraceSource.WriteInfo(
                TraceType,
                "Configuration change delivery to application instance manager is enabled.");
        }
예제 #2
0
        internal ContainerManager(AppInstanceManager appInstanceManager, ContainerEnvironment containerEnvironment)
        {
            this.appInstanceManager   = appInstanceManager;
            this.containerEnvironment = containerEnvironment;

            Utility.TraceSource.WriteInfo(
                TraceType,
                "Watching directory for creation of new container trace folders {0}",
                this.containerEnvironment.ContainerLogRootDirectory);

            // Watcher needs to be created before startup listing of folders
            // Otherwise there is the risk a file will be created between the two and it will be missed.
            // WriteLock is created so prevent race condition with file watchers
            this.processingMarkersRWLock.EnterWriteLock();
            try
            {
                if (Directory.Exists(this.containerEnvironment.ContainerLogRootDirectory))
                {
                    this.CreateContainerFolderWacher();

                    foreach (var directory in Directory.EnumerateDirectories(this.containerEnvironment.ContainerLogRootDirectory))
                    {
                        this.ContainerLogFolderProcessingStartup(directory);
                    }
                }
                else
                {
                    Utility.TraceSource.WriteError(
                        TraceType,
                        "Not monitoring directory for creation of new container trace folders since directory doesn't exist {0}",
                        this.containerEnvironment.ContainerLogRootDirectory);
                }
            }
            finally
            {
                this.processingMarkersRWLock.ExitWriteLock();
            }

            // Arm the cleanup timer.
            this.cleanupTimer = new DcaTimer(
                ContainerManager.TraceType,
                new TimerCallback(this.BackgroundCleanup),
                (long)this.containerEnvironment.ContainerFolderCleanupTimerInterval.TotalMilliseconds);
            this.cleanupTimer.Start((long)this.containerEnvironment.ContainerFolderCleanupTimerInterval.TotalMilliseconds);
        }
        public ContainerManager(AppInstanceManager appInstanceManager)
        {
            Utility.TraceSource.WriteInfo(TraceType, "Watching directory for creation of new container trace folders {0}", ContainerEnvironment.ContainerLogRootDirectory);
            this.appInstanceManager = appInstanceManager;
            if (Directory.Exists(ContainerEnvironment.ContainerLogRootDirectory))
            {
                foreach (var directory in Directory.EnumerateDirectories(ContainerEnvironment.ContainerLogRootDirectory))
                {
                    var subDirectory  = Path.GetFileName(directory);
                    var appInstanceId = Path.Combine(ContainerEnvironment.ContainersRootFolderName, subDirectory);
                    Utility.TraceSource.WriteInfo(TraceType, "Reading container traces from {0}", appInstanceId);
                    if (!File.Exists(Path.Combine(directory, ContainerEnvironment.ContainerDeletionMarkerFileName)))
                    {
                        this.appInstanceManager.CreateApplicationInstance(appInstanceId, null);
                    }
                    else
                    {
                        this.applicationInstancesToDelete.Add(appInstanceId);
                    }
                }
            }
            else
            {
                Directory.CreateDirectory(ContainerEnvironment.ContainerLogRootDirectory);
            }

            // Arm FSW to watch for new folders.
            this.watcher                     = new FileSystemWatcher(ContainerEnvironment.ContainerLogRootDirectory);
            this.watcher.Created            += this.OnFolderCreated;
            this.watcher.EnableRaisingEvents = true;

            // Arm the cleanup timer.
            this.cleanupTimer = new DcaTimer(
                ContainerManager.TraceType,
                new TimerCallback(this.BackgroundCleanup),
                (long)TimeSpan.FromMinutes(10.0).TotalMilliseconds);
            this.cleanupTimer.Start();
        }
예제 #4
0
        public static int Main(string[] args)
        {
            Utility.TraceSource = null;

#if !DotNetCoreClr
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
#endif

#if !DotNetCoreClrLinux && !DotNetCoreClrIOT
            // Register an unhandled exception event handler
            AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler.OnUnhandledException;
#endif

            // Initialize config store
            ConfigUpdateHandler configUpdateHandler = new ConfigUpdateHandler();
            Utility.InitializeConfigStore(configUpdateHandler);

            // Initialize the Fabric node Id
            Utility.InitializeFabricNodeInfo();

            // Read FabricHost's exit failure reset time from settings
            UnhandledExceptionHandler.ReadFabricHostExitFailureResetTime();

            // Set up tracing
            Utility.InitializeTracing();
            Utility.TraceSource = new FabricEvents.ExtensionsEvents(FabricEvents.Tasks.FabricDCA);

            Utility.DcaProgramDirectory = Path.Combine(Path.GetDirectoryName(FabricEnvironment.GetCodePath()), "DCA.Code");

            // Initialize the work directory
            Utility.InitializeWorkDirectory();

            // Create the event that indicates when the main thread should
            // stop the DCA
            stopDCAEvent = new ManualResetEvent(false);
            UnhandledExceptionHandler.StopDcaEvent = stopDCAEvent;

            // Create the event that indicates that the main thread has
            // stopped the DCA.
            dcaHasStoppedEvent = new ManualResetEvent(false);

            // Register to be notified when we need to stop.
            Console.CancelKeyPress += CtrlCHandler;

            // The configuration update handler makes use of some members that we just
            // initialized above, e.g. the trace source and the event used to indicate
            // that the DCA should stop.
            //
            // Until we initialize these members, it is not safe for the the configuration
            // update handler to process any updates because it would end up trying to
            // access those uninitialized members. Therefore the configuration update
            // handler ignores these updates until this point. This is okay, because we
            // haven't attempted to read configurations until now. When we read the
            // configurations later, we will be reading the updated values anyway, so
            // ignoring the update notifications is not a problem.
            //
            // Now that we have initialized all the members needed by the configuration
            // update handler, we tell it to start processing configuration updates.
            configUpdateHandler.StartProcessingConfigUpdates();

            // Create and initialize the application instance manager object.
            AppInstanceManager appInstanceMgr = new AppInstanceManager();

            // Notify the application instance manager about the availability of the
            // Windows Fabric application.
            appInstanceMgr.CreateApplicationInstance(Utility.WindowsFabricApplicationInstanceId, null);

            // Let the config update handler know that the Windows Fabric
            // Application has been created, so that it can send configuration
            // updates if it needs to.
            configUpdateHandler.StartConfigUpdateDeliveryToAppInstanceMgr(appInstanceMgr);

            // Create and initialize the service package table manager object
            ServicePackageTableManager servicePackageTableManager = new ServicePackageTableManager(appInstanceMgr);

            // Create and initialize the container manager object if required.
            ContainerManager     containerManager     = null;
            ContainerEnvironment containerEnvironment = null;

            // FabricContainerAppsEnabled is set to true by default
            bool enableContainerManager = Utility.GetUnencryptedConfigValue <bool>(
                ConfigReader.HostingSectionName,
                ConfigReader.FabricContainerAppsEnabledParameterName,
                true);

            if (enableContainerManager)
            {
                containerEnvironment = new ContainerEnvironment();
                containerManager     = new ContainerManager(appInstanceMgr, containerEnvironment);
            }

            // DCA is running again.
            HealthClient.ClearNodeHealthReport();

            // Wait for the event that is signaled when the DCA needs to be
            // stopped.
            stopDCAEvent.WaitOne();

            // Stop the DCA's periodic activities
            Utility.TraceSource.WriteInfo(
                TraceType,
                "Stopping the DCA ...");

            servicePackageTableManager.Dispose();
            configUpdateHandler.Dispose();
            appInstanceMgr.Dispose();

            Utility.TraceSource.WriteInfo(
                TraceType,
                "DCA has stopped.");

            // Set event to indicate that the main thread has stopped the DCA
            bool result = dcaHasStoppedEvent.Set();
            System.Fabric.Interop.Utility.ReleaseAssert(
                result,
                StringResources.DCAError_SignalEventToStopFailed);

            return(0);
        }
예제 #5
0
        internal ServicePackageTableManager(AppInstanceManager appInstanceMgr)
        {
            this.applicationInstanceManager = appInstanceMgr;
            this.servicePackageTable        = new ServicePackageTable();

            // Get the interval at which we need to read ETL files
            int servicePackageNotificationIntervalSeconds = Utility.GetUnencryptedConfigValue(
                HostingSectionName,
                ServicePackageNotificationIntervalInSecondsParamName,
                DefaultServicePackageNotificationIntervalInSeconds);

            this.maxServicePackageInactiveTimeSeconds = servicePackageNotificationIntervalSeconds * MaxServicePackageInactiveTimeMultiplier;
            Utility.TraceSource.WriteInfo(
                TraceType,
                "Interval at which we check for inactive service packages: {0} seconds.",
                servicePackageNotificationIntervalSeconds);
            Utility.TraceSource.WriteInfo(
                TraceType,
                "Maximum time for which a service package can remain inactive before being deleted: {0} seconds.",
                this.maxServicePackageInactiveTimeSeconds);

            // Create the folder where the backup files are stored
            string tableBackupDirectory = Path.Combine(
                Utility.LogDirectory,
                AppInstanceDataDirName,
                AppInstanceTableDirName);

            FabricDirectory.CreateDirectory(tableBackupDirectory);

            // Initialize the application activation table
            AppActivationTable.Initialize(tableBackupDirectory);

            // Retrieve the file where we last saved the service package table
            this.tableBackup = new ServicePackageTableBackup(
                tableBackupDirectory,
                this.AddOrUpdateServicePackage);

            // Initialize the service package table from the file that we last saved.
            if (false == this.tableBackup.Read())
            {
                Utility.TraceSource.WriteError(
                    TraceType,
                    "Unable to initialize service package table from backup file on disk.");
            }

            // Initialize the timestamp up to which ETW events can be read
            Utility.ApplicationEtwTracesEndTime = this.tableBackup.LatestBackupTime.Timestamp;

            // Compute the directory containing ETL files containing information about
            // application instances
            string etlFileDirectory = Path.Combine(
                Utility.LogDirectory,
                AppInstanceDataDirName,
                AppInstanceDataEtlDirName);

            FabricDirectory.CreateDirectory(etlFileDirectory);

#if !DotNetCoreClrLinux
            // Create the object that reads events from ETL files.
            this.etlFileReader = new AppInstanceEtlFileDataReader(
                etlFileDirectory,
                this.tableBackup,
                this.AddOrUpdateServicePackage,
                this.RemoveServicePackage);
#endif

            long inactiveServicePackageScanIntervalMillisec = ((long)servicePackageNotificationIntervalSeconds) * 1000;
            this.inactiveServicePackageScanTimer = new DcaTimer(
                InactiveServicePackageScanTimerId,
                this.MarkInactiveServicePackagesForDeletion,
                inactiveServicePackageScanIntervalMillisec);
            this.inactiveServicePackageScanTimer.Start();
        }