internal void ReloadConfigOnTimer(object state) { LoggingConfiguration configurationToReload = (LoggingConfiguration)state; InternalLogger.Info("Reloading configuration..."); lock (this) { if (_reloadTimer != null) { _reloadTimer.Dispose(); _reloadTimer = null; } _watcher.StopWatching(); try { if (Configuration != configurationToReload) { throw new Exception("Config changed in between. Not reloading."); } LoggingConfiguration newConfig = configurationToReload.Reload(); if (newConfig != null) { Configuration = newConfig; if (ConfigurationReloaded != null) { ConfigurationReloaded(true, null); } } else { throw new Exception("Configuration.Reload() returned null. Not reloading."); } } catch (Exception ex) { _watcher.Watch(configurationToReload.FileNamesToWatch); if (ConfigurationReloaded != null) { ConfigurationReloaded(false, ex); } } } }
/// <summary> /// It allocates the first slot in the list when the file name does not already in the list and clean up any /// unused slots. /// </summary> /// <param name="fileName">File name associated with a single appender.</param> /// <returns>The allocated appender.</returns> /// <exception cref="NullReferenceException"> /// Thrown when <see cref="M:AllocateAppender"/> is called on an <c>Empty</c><see cref="FileAppenderCache"/> instance. /// </exception> public BaseFileAppender AllocateAppender(string fileName) { // // BaseFileAppender.Write is the most expensive operation here // so the in-memory data structure doesn't have to be // very sophisticated. It's a table-based LRU, where we move // the used element to become the first one. // The number of items is usually very limited so the // performance should be equivalent to the one of the hashtable. // BaseFileAppender appenderToWrite = null; int freeSpot = appenders.Length - 1; for (int i = 0; i < appenders.Length; ++i) { // Use empty slot in recent appender list, if there is one. if (appenders[i] == null) { freeSpot = i; break; } if (appenders[i].FileName == fileName) { // found it, move it to the first place on the list // (MRU) // file open has a chance of failure // if it fails in the constructor, we won't modify any data structures BaseFileAppender app = appenders[i]; for (int j = i; j > 0; --j) { appenders[j] = appenders[j - 1]; } appenders[0] = app; appenderToWrite = app; break; } } if (appenderToWrite == null) { BaseFileAppender newAppender = Factory.Open(fileName, CreateFileParameters); if (appenders[freeSpot] != null) { CloseAppender(appenders[freeSpot]); appenders[freeSpot] = null; } for (int j = freeSpot; j > 0; --j) { appenders[j] = appenders[j - 1]; } appenders[0] = newAppender; appenderToWrite = newAppender; #if !SILVERLIGHT && !__IOS__ && !__ANDROID__ if (!string.IsNullOrEmpty(archiveFilePatternToWatch)) { var archiveFilePatternToWatchPath = GetFullPathForPattern(archiveFilePatternToWatch); string directoryPath = Path.GetDirectoryName(archiveFilePatternToWatchPath); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } externalFileArchivingWatcher.Watch(archiveFilePatternToWatchPath); } #endif } return(appenderToWrite); }
/// <summary> /// It allocates the first slot in the list when the file name does not already in the list and clean up any /// unused slots. /// </summary> /// <param name="fileName">File name associated with a single appender.</param> /// <returns>The allocated appender.</returns> /// <exception cref="NullReferenceException"> /// Thrown when <see cref="M:AllocateAppender"/> is called on an <c>Empty</c><see cref="FileAppenderCache"/> instance. /// </exception> public BaseFileAppender AllocateAppender(string fileName) { // // BaseFileAppender.Write is the most expensive operation here // so the in-memory data structure doesn't have to be // very sophisticated. It's a table-based LRU, where we move // the used element to become the first one. // The number of items is usually very limited so the // performance should be equivalent to the one of the hashtable. // BaseFileAppender appenderToWrite = null; int freeSpot = appenders.Length - 1; for (int i = 0; i < appenders.Length; ++i) { // Use empty slot in recent appender list, if there is one. if (appenders[i] == null) { freeSpot = i; break; } if (string.Equals(appenders[i].FileName, fileName, StringComparison.OrdinalIgnoreCase)) { // found it, move it to the first place on the list // (MRU) BaseFileAppender app = appenders[i]; if (i > 0) { // file open has a chance of failure // if it fails in the constructor, we won't modify any data structures for (int j = i; j > 0; --j) { appenders[j] = appenders[j - 1]; } appenders[0] = app; } appenderToWrite = app; break; } } if (appenderToWrite == null) { try { InternalLogger.Debug("Creating file appender: {0}", fileName); BaseFileAppender newAppender = Factory.Open(fileName, CreateFileParameters); if (appenders[freeSpot] != null) { CloseAppender(appenders[freeSpot], "Stale", false); appenders[freeSpot] = null; } for (int j = freeSpot; j > 0; --j) { appenders[j] = appenders[j - 1]; } appenders[0] = newAppender; appenderToWrite = newAppender; if (CheckCloseAppenders != null) { #if !SILVERLIGHT && !__IOS__ && !__ANDROID__ if (freeSpot == 0) { logFileWasArchived = false; } if (!string.IsNullOrEmpty(archiveFilePatternToWatch)) { string directoryPath = Path.GetDirectoryName(archiveFilePatternToWatch); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); } externalFileArchivingWatcher.Watch(archiveFilePatternToWatch); // Always monitor the archive-folder } externalFileArchivingWatcher.Watch(appenderToWrite.FileName); // Monitor the active file-appender #endif } } catch (Exception ex) { InternalLogger.Warn(ex, "Failed to create file appender: {0}", fileName); throw; } } return(appenderToWrite); }
/// <summary> /// Should only be called by Project.QueueEffectUpdate(Effect). /// Doesn't run on the main thread. /// </summary> public override void Update() { if (!scriptContainer.HasScript) { return; } var newDependencyWatcher = new MultiFileWatcher(); newDependencyWatcher.OnFileChanged += (sender, e) => { if (IsDisposed) { return; } Refresh(); }; var context = new EditorGeneratorContext(this, Project.ProjectFolderPath, Project.MapsetPath, Project.MainBeatmap, Project.MapsetManager.Beatmaps, newDependencyWatcher); var success = false; try { changeStatus(EffectStatus.Loading); var script = scriptContainer.CreateScript(); changeStatus(EffectStatus.Configuring); Program.RunMainThread(() => { beatmapDependant = true; if (script.Identifier != configScriptIdentifier) { script.UpdateConfiguration(Config); configScriptIdentifier = script.Identifier; RaiseConfigFieldsChanged(); } else { script.ApplyConfiguration(Config); } }); changeStatus(EffectStatus.Updating); script.Generate(context); foreach (var layer in context.EditorLayers) { layer.PostProcess(); } success = true; } catch (RemotingException e) { Debug.Print($"Script execution failed with RemotingException, reloading {BaseName} ({e.Message})"); changeStatus(EffectStatus.ReloadPending); Program.Schedule(() => { if (Project.IsDisposed) { return; } scriptContainer.ReloadScript(); }); return; } catch (ScriptCompilationException e) { Debug.Print($"Script compilation failed for {BaseName}\n{e.Message}"); changeStatus(EffectStatus.CompilationFailed, e.Message, context.Log); return; } catch (ScriptLoadingException e) { Debug.Print($"Script load failed for {BaseName}\n{e.ToString()}"); changeStatus(EffectStatus.LoadingFailed, e.InnerException != null ? $"{e.Message}: {e.InnerException.Message}" : e.Message, context.Log); return; } catch (Exception e) { changeStatus(EffectStatus.ExecutionFailed, getExecutionFailedMessage(e), context.Log); return; } finally { if (!success) { if (dependencyWatcher != null) { dependencyWatcher.Watch(newDependencyWatcher.WatchedFilenames); newDependencyWatcher.Dispose(); newDependencyWatcher = null; } else { dependencyWatcher = newDependencyWatcher; } } context.DisposeResources(); } changeStatus(EffectStatus.Ready, null, context.Log); Program.Schedule(() => { if (IsDisposed) { newDependencyWatcher.Dispose(); return; } beatmapDependant = context.BeatmapDependent; dependencyWatcher?.Dispose(); dependencyWatcher = newDependencyWatcher; if (Project.IsDisposed) { return; } if (placeHolderLayer != null) { Project.LayerManager.Replace(placeHolderLayer, context.EditorLayers); placeHolderLayer = null; } else { Project.LayerManager.Replace(layers, context.EditorLayers); } layers = context.EditorLayers; refreshLayerNames(); refreshEstimatedSize(); }); }
internal void ReloadConfigOnTimer(object state) { if (_reloadTimer == null && _isDisposing) { return; //timer was disposed already. } LoggingConfiguration oldConfig = (LoggingConfiguration)state; InternalLogger.Info("Reloading configuration..."); lock (_logFactory._syncRoot) { LoggingConfiguration newConfig; try { if (_isDisposing) { return; //timer was disposed already. } var currentTimer = _reloadTimer; if (currentTimer != null) { _reloadTimer = null; currentTimer.WaitForDispose(TimeSpan.Zero); } if (_logFactory._config != oldConfig) { InternalLogger.Warn("NLog Config changed in between. Not reloading."); return; } newConfig = oldConfig.Reload(); //problem: XmlLoggingConfiguration.Initialize eats exception with invalid XML. ALso XmlLoggingConfiguration.Reload never returns null. //therefor we check the InitializeSucceeded property. if (newConfig is XmlLoggingConfiguration xmlConfig && xmlConfig.InitializeSucceeded != true) { InternalLogger.Warn("NLog Config Reload() failed. Invalid XML?"); return; } } catch (Exception exception) { if (exception.MustBeRethrownImmediately()) { throw; // Throwing exceptions here will crash the entire application (.NET 2.0 behavior) } InternalLogger.Warn(exception, "NLog configuration failed to reload"); _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(false, exception)); return; } try { TryUnwatchConfigFile(); if (newConfig != null) { if (_logFactory.KeepVariablesOnReload && _logFactory._config != null) { newConfig.CopyVariables(_logFactory._config.Variables); } _logFactory.Configuration = newConfig; // Triggers LogFactory to call Activated(...) that adds file-watch again _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(true)); } } catch (Exception exception) { if (exception.MustBeRethrownImmediately()) { throw; // Throwing exceptions here will crash the entire application (.NET 2.0 behavior) } InternalLogger.Warn(exception, "NLog configuration reloaded, failed to be assigned"); _watcher.Watch(oldConfig.FileNamesToWatch); _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(false, exception)); } } }
internal void ReloadConfigOnTimer(object state) { if (_reloadTimer == null && _isDisposing) { return; //timer was disposed already. } LoggingConfiguration oldConfig = (LoggingConfiguration)state; InternalLogger.Info("Reloading configuration..."); lock (_lockObject) { if (_isDisposing) { return; //timer was disposed already. } var currentTimer = _reloadTimer; if (currentTimer != null) { _reloadTimer = null; currentTimer.WaitForDispose(TimeSpan.Zero); } } lock (_logFactory._syncRoot) { LoggingConfiguration newConfig; try { if (!ReferenceEquals(_logFactory._config, oldConfig)) { InternalLogger.Warn("NLog Config changed in between. Not reloading."); return; } newConfig = oldConfig.ReloadNewConfig(); if (newConfig == null || ReferenceEquals(newConfig, oldConfig)) { return; } } catch (Exception exception) { if (exception.MustBeRethrownImmediately()) { throw; // Throwing exceptions here will crash the entire application (.NET 2.0 behavior) } InternalLogger.Warn(exception, "NLog configuration failed to reload"); _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(false, exception)); return; } try { TryUnwatchConfigFile(); _logFactory.Configuration = newConfig; // Triggers LogFactory to call Activated(...) that adds file-watch again _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(true)); } catch (Exception exception) { if (exception.MustBeRethrownImmediately()) { throw; // Throwing exceptions here will crash the entire application (.NET 2.0 behavior) } InternalLogger.Warn(exception, "NLog configuration reloaded, failed to be assigned"); _watcher.Watch(oldConfig.FileNamesToWatch); _logFactory?.NotifyConfigurationReloaded(new LoggingConfigurationReloadedEventArgs(false, exception)); } } }
public override void AddDependency(string path) => watcher.Watch(path);