/// <summary> /// Starts the backup engines. /// </summary> /// <returns>True if successful, otherwise false.</returns> private async Task <bool> StartBackupEnginesAsync() { // each backup engine instance shares the same logger. // this means a single log file for all engine instances- and each engine will prepend its log messages with a context tag. try { BackupEngineInstances = new List <BackupEngine>(); var instanceCountSettingName = ArchivialLibrary.Constants.RuntimeSettingNames.BackupEngineInstancesCount; var instanceCount = Convert.ToInt32(await ClientDatabase.GetApplicationOptionAsync(instanceCountSettingName).ConfigureAwait(false)); var startupDelaySettingName = ArchivialLibrary.Constants.RuntimeSettingNames.BackupEngineStartupDelayInSeconds; var startupDelaySeconds = Convert.ToInt32(await ClientDatabase.GetApplicationOptionAsync(startupDelaySettingName).ConfigureAwait(false)); for (int i = 0; i < instanceCount; i++) { CoreLog.WriteSystemEvent( string.Format("Waiting {0} seconds between Backup Engine starts to reduce sudden filesystem load.", startupDelaySeconds), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.BackupEngineWaitingForNextStart, true); await Task.Delay(TimeSpan.FromSeconds(startupDelaySeconds)).ConfigureAwait(false); var engineLog = new Logger(string.Format("{0}-{1}", ArchivialLibrary.Constants.Logging.BackupComponentName, i)); engineLog.Start( CoreSettings.GetEventlogName(), CoreSettings.GetEventlogName(), CoreSettings.GetLogFilesDirectory()); var instance = new BackupEngine(ClientDatabase, engineLog, i, CoreSettings); instance.Stopped += Backup_Stopped; instance.BeginStart(); BackupEngineInstances.Add(instance); CoreLog.WriteSystemEvent( string.Format("Backup Engine instance {0} has started.", i), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StartedBackupEngine, true); } return(true); } catch (Exception ex) { var message = "Failed to start the backup engine."; var context = CoreLog.GenerateFullContextStackTrace(); CoreLog.WriteSystemEvent(message, ex, context, ArchivialLibrary.Constants.EventIDs.FailedBackupEngine, true); return(false); } }
/// <summary> /// Runs when the service stop is triggered. /// </summary> protected override void OnStop() { if (CoreLog != null) { CoreLog.WriteSystemEvent( string.Format("Stopping {0} client service.", ArchivialLibrary.Constants.Logging.AppName), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StoppingService, true); } if (CoreServiceEngineInstance != null) { CoreServiceEngineInstance.BeginStop(); } if (ScanEngineInstance != null) { ScanEngineInstance.BeginStop(); } if (BackupEngineInstances != null) { foreach (var instance in BackupEngineInstances) { instance.BeginStop(); } } if (CleanupEngineInstances != null) { foreach (var instance in CleanupEngineInstances) { instance.BeginStop(); } } if (ConnectionEngineInstance != null) { ConnectionEngineInstance.BeginStop(); } if (StatusEngineInstance != null) { StatusEngineInstance.BeginStop(); } if (CoreLog != null) { CoreLog.WriteSystemEvent( string.Format("Successfully stopped {0} client service.", ArchivialLibrary.Constants.Logging.AppName), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StoppedService, true); } }
/// <summary> /// Configures the database instance. /// </summary> /// <returns></returns> private async Task <bool> ConfigureDatabaseAsync() { try { ClientDatabase = new SQLServerClientDatabase(CoreSettings.GetDatabaseConnectionString(), CoreLog, CoreSettings); await ClientDatabase.PrepareDatabaseAsync().ConfigureAwait(false); return(true); } catch (Exception ex) { var message = "Failed to configure client database."; var context = CoreLog.GenerateFullContextStackTrace(); CoreLog.WriteSystemEvent(message, ex, context, ArchivialLibrary.Constants.EventIDs.FailedToPrepareClientDatabase, true); return(false); } }
/// <summary> /// Starts the cleanup engine(s). /// </summary> /// <returns>True if successful, otherwise false.</returns> private async Task <bool> StartCleanupEnginesAsync() { // each cleanup engine instance shares the same logger. // this means a single log file for all engine instances- and each engine will prepend its log messages with a context tag. try { CleanupEngineInstances = new List <CleanupEngine>(); var settingName = ArchivialLibrary.Constants.RuntimeSettingNames.CleanupEngineInstancesCount; var instanceCount = Convert.ToInt32(await ClientDatabase.GetApplicationOptionAsync(settingName).ConfigureAwait(false)); for (int i = 0; i < instanceCount; i++) { var engineLog = new Logger(string.Format("{0}-{1}", ArchivialLibrary.Constants.Logging.CleanupComponentName, i)); engineLog.Start( CoreSettings.GetEventlogName(), CoreSettings.GetEventlogName(), CoreSettings.GetLogFilesDirectory()); var instance = new CleanupEngine(ClientDatabase, engineLog, i, CoreSettings); instance.Stopped += Cleanup_Stopped; instance.BeginStart(); CleanupEngineInstances.Add(instance); CoreLog.WriteSystemEvent( string.Format("Cleanup Engine instance {0} has started.", i), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StartedCleanupEngine, true); } return(true); } catch (Exception ex) { var message = "Failed to start the cleanup engine(s)."; var context = CoreLog.GenerateFullContextStackTrace(); CoreLog.WriteSystemEvent(message, ex, context, ArchivialLibrary.Constants.EventIDs.FailedCleanupEngine, true); return(false); } }
/// <summary> /// Callback event for when the cleanup engine has stopped. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Cleanup_Stopped(object sender, ArchivialLibrary.Events.EngineStoppedEventArgs e) { if (e.Reason == ArchivialLibrary.Events.EngineStoppedReason.Failed) { CoreLog.WriteSystemEvent( string.Format("Cleanup Engine instance {0} has failed.", e.EngineID), e.Exception, CoreLog.GenerateFullContextStackTrace(), ArchivialLibrary.Constants.EventIDs.FailedCleanupEngine, true); } else if (e.Reason == ArchivialLibrary.Events.EngineStoppedReason.StopRequested) { CoreLog.WriteSystemEvent( string.Format("Cleanup Engine instance {0} has stopped.", e.EngineID), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StoppedCleanupEngine, true); } else { throw new InvalidOperationException("Unexpected EngineStoppedReason: " + e.Reason); } }
/// <summary> /// Starts the scanning engine. /// </summary> /// <returns>True if successful, otherwise false.</returns> private bool StartScanEngine() { try { ScanEngineInstance = new ScanEngine(ClientDatabase, ScanEngineLog, 0, CoreSettings); ScanEngineInstance.Stopped += Scan_Stopped; ScanEngineInstance.BeginStart(); CoreLog.WriteSystemEvent( string.Format("Scanning Engine has started."), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StartedScanEngine, true); return(true); } catch (Exception ex) { var message = "Failed to start the scanning engine."; var context = CoreLog.GenerateFullContextStackTrace(); CoreLog.WriteSystemEvent(message, ex, context, ArchivialLibrary.Constants.EventIDs.FailedScanEngine, true); return(false); } }
/// <summary> /// Core application start. /// </summary> private void CoreStart() { CoreSettings = new WindowsCoreSettings(); StartLoggers(); CoreLog.WriteSystemEvent( string.Format("Starting {0} client service version {1}.", ArchivialLibrary.Constants.Logging.AppName, Assembly.GetExecutingAssembly().GetName().Version.ToString()), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StartingService, true); var dbTask = ConfigureDatabaseAsync(); dbTask.Wait(); if (!dbTask.Result) { Stop(); return; } if (!StartCoreServiceEngine()) { Stop(); return; } if (!StartConnectionEngine()) { Stop(); return; } if (!StartStatusEngine()) { Stop(); return; } if (!StartScanEngine()) { Stop(); return; } var beTask = StartBackupEnginesAsync(); beTask.Wait(); if (!beTask.Result) { Stop(); return; } var cleTask = StartCleanupEnginesAsync(); cleTask.Wait(); if (!cleTask.Result) { Stop(); return; } CoreLog.WriteSystemEvent( string.Format("Successfully started {0} client service.", ArchivialLibrary.Constants.Logging.AppName), EventLogEntryType.Information, ArchivialLibrary.Constants.EventIDs.StartedService, true); }