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."); }
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(); }
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); }
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(); }