/// <summary> /// Creates a new instance of the <see cref="LogicalThread"/> class. /// </summary> /// <param name="scheduler">The <see cref="LogicalThreadScheduler"/> that created this thread.</param> /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception> internal LogicalThread(LogicalThreadScheduler scheduler) { if ((object)scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } m_scheduler = scheduler; m_queues = new ConcurrentQueue <Action> [PriorityLevels]; m_threadLocalStorage = new Dictionary <object, object>(); m_nextExecutionToken = new CancellationToken(); m_statistics = new LogicalThreadStatistics(); for (int i = 0; i < m_queues.Length; i++) { m_queues[i] = new ConcurrentQueue <Action>(); } }
/// <summary> /// Creates a new instance of the <see cref="LogicalThread"/> class. /// </summary> /// <param name="scheduler">The <see cref="LogicalThreadScheduler"/> that created this thread.</param> /// <param name="priorityLevels">The number of levels of priority supported by this logical thread.</param> /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="priorityLevels"/> is less than or equal to zero.</exception> internal LogicalThread(LogicalThreadScheduler scheduler, int priorityLevels) { if ((object)scheduler == null) { throw new ArgumentNullException(nameof(scheduler)); } if (priorityLevels <= 0) { throw new ArgumentException($"A logical thread must have at least one priority level.", nameof(priorityLevels)); } m_scheduler = scheduler; m_queues = new ConcurrentQueue <Action> [priorityLevels]; m_threadLocalStorage = new Dictionary <object, object>(); m_statistics = new LogicalThreadStatistics(); for (int i = 0; i < m_queues.Length; i++) { m_queues[i] = new ConcurrentQueue <Action>(); } }
/// <summary> /// Creates a new instance of the <see cref="LogicalThread"/> class. /// </summary> /// <param name="scheduler">The <see cref="LogicalThreadScheduler"/> that created this thread.</param> /// <param name="priorityLevels">The number of levels of priority supported by this logical thread.</param> /// <exception cref="ArgumentNullException"><paramref name="scheduler"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="priorityLevels"/> is less than or equal to zero.</exception> internal LogicalThread(LogicalThreadScheduler scheduler, int priorityLevels) { if ((object)scheduler == null) throw new ArgumentNullException(nameof(scheduler)); if (priorityLevels <= 0) throw new ArgumentException($"A logical thread must have at least one priority level.", nameof(priorityLevels)); m_scheduler = scheduler; m_queues = new ConcurrentQueue<Action>[priorityLevels]; m_threadLocalStorage = new Dictionary<object, object>(); m_statistics = new LogicalThreadStatistics(); for (int i = 0; i < m_queues.Length; i++) m_queues[i] = new ConcurrentQueue<Action>(); }
/// <summary> /// Starts the fault location engine. /// </summary> public void Start() { IEnumerable<string> filterPatterns; // Get system settings from the database ReloadSystemSettings(); // Get the list of file extensions to be processed by openXDA using (SystemInfoDataContext systemInfo = new SystemInfoDataContext(m_dbConnectionString)) { filterPatterns = systemInfo.DataReaders .Select(reader => reader.FilePattern) .Select(extension => string.Format("*.{0}", extension)) .ToList(); } // Reload configuration at startup ReloadConfiguration(); // Make sure watch directories exist foreach (string path in m_systemSettings.WatchDirectoryList) TryCreateDirectory(path); // Make sure results directory exists TryCreateDirectory(m_systemSettings.ResultsPath); if ((object)m_fileWrapperLookup == null) m_fileWrapperLookup = new Dictionary<string, FileWrapper>(); // Create the lookup table used to track which files are being processed if ((object)m_activeFiles == null) m_activeFiles = new ConcurrentDictionary<string, string>(); // Create the scheduler used to schedule when to process meter data if ((object)m_meterDataScheduler == null) { m_meterDataScheduler = new LogicalThreadScheduler(); m_meterDataThreadLookup = new Dictionary<string, LogicalThread>(); m_meterDataScheduler.UnhandledException += (sender, args) => { string message = $"Unhandled exception occurred while processing meter data: {args.Argument.Message}"; Exception ex = new Exception(message, args.Argument); OnProcessException(ex); }; } m_meterDataScheduler.MaxThreadCount = m_systemSettings.ProcessingThreadCount; // Setup new file processor to monitor the watch directories if ((object)m_fileProcessor == null) { m_fileProcessor = new FileProcessor(FileProcessorID); m_fileProcessor.InternalBufferSize = m_systemSettings.FileWatcherBufferSize; m_fileProcessor.EnumerationStrategy = m_systemSettings.FileWatcherEnumerationStrategy; m_fileProcessor.MaxThreadCount = m_systemSettings.FileWatcherInternalThreadCount; m_fileProcessor.MaxFragmentation = m_systemSettings.FileWatcherMaxFragmentation; m_fileProcessor.FilterMethod = PrevalidateFile; m_fileProcessor.Processing += FileProcessor_Processing; m_fileProcessor.Error += FileProcessor_Error; UpdateFileProcessorFilter(m_systemSettings); } foreach (string path in m_systemSettings.WatchDirectoryList) m_fileProcessor.AddTrackedDirectory(path); }
/// <summary> /// Initializes a new instance of the <see cref="ServiceHelper"/> class. /// </summary> public ServiceHelper() { m_telnetSessionPassword = "******"; m_logStatusUpdates = DefaultLogStatusUpdates; m_maxStatusUpdatesLength = DefaultMaxStatusUpdatesLength; m_maxStatusUpdatesFrequency = DefaultMaxStatusUpdatesFrequency; m_monitorServiceHealth = DefaultMonitorServiceHealth; m_healthMonitorInterval = DefaultHealthMonitorInterval; m_requestHistoryLimit = DefaultRequestHistoryLimit; m_supportFileManagementCommands = DefaultSupportFileManagementCommands; m_supportTelnetSessions = DefaultSupportTelnetSessions; m_supportSystemCommands = DefaultSupportSystemCommands; m_secureRemoteInteractions = DefaultSecureRemoteInteractions; m_serializationFormat = DefaultSerializationFormat; m_persistSettings = DefaultPersistSettings; m_settingsCategory = DefaultSettingsCategory; m_processes = new List<ServiceProcess>(); m_remoteClients = new List<ClientInfo>(); m_clientRequestHistory = new List<ClientRequestInfo>(); m_serviceComponents = new List<object>(); m_clientRequestHandlers = new List<ClientRequestHandler>(); m_componentEnabledStates = new Dictionary<ISupportLifecycle, bool>(); m_clientStatusUpdateLookup = new Dictionary<Guid, ClientStatusUpdateConfiguration>(); m_threadScheduler = new LogicalThreadScheduler(); m_threadScheduler.UnhandledException += LogicalThread_ProcessException; m_statusUpdateThread = m_threadScheduler.CreateThread(2); m_statusUpdateQueue = new List<StatusUpdate>(); // Components m_statusLog = new LogFile(); m_statusLog.FileName = "StatusLog.txt"; m_statusLog.SettingsCategory = "StatusLog"; m_statusLog.LogException += StatusLog_LogException; m_processScheduler = new ScheduleManager(); m_processScheduler.SettingsCategory = "ProcessScheduler"; m_processScheduler.ScheduleDue += Scheduler_ScheduleDue; m_errorLogger = new ErrorLogger(); m_errorLogger.ExitOnUnhandledException = false; m_errorLogger.SettingsCategory = "ErrorLogger"; m_errorLogger.ErrorLog.SettingsCategory = "ErrorLog"; m_errorLogger.LoggingException += ErrorLogger_LoggingException; }
/// <summary> /// Creates a new instance of the <see cref="FileProcessor"/> class. /// </summary> /// <param name="processorID">Identifies the file processor so that it can locate its processed file cache.</param> public FileProcessor(Guid processorID) { m_processorID = processorID; m_filter = DefaultFilter; m_filterMethod = filePath => true; m_trackChanges = DefaultTrackChanges; m_cachePath = DefaultCachePath; m_internalBufferSize = DefaultInternalBufferSize; m_maxFragmentation = DefaultMaxFragmentation; m_enumerationStrategy = DefaultEnumerationStrategy; m_fileWatchersLock = new object(); m_fileWatchers = new List<SafeFileWatcher>(); m_threadScheduler = new LogicalThreadScheduler(); m_threadScheduler.UnhandledException += (sender, args) => OnError(args.Argument); m_processingThread = m_threadScheduler.CreateThread(2); m_watcherThread = m_threadScheduler.CreateThread(); m_fileWatchTimer = new Timer(15000); m_fileWatchTimer.Elapsed += FileWatchTimer_Elapsed; m_waitObject = new ManualResetEvent(false); m_touchedFiles = new Dictionary<string, DateTime>(StringComparer.OrdinalIgnoreCase); m_processedFiles = new FileBackedHashSet<string>(Path.Combine(m_cachePath, m_processorID.ToString()), StringComparer.OrdinalIgnoreCase); // Create the enumerator last since we are passing // a reference to 'this' into its constructor m_enumerator = new FileEnumerator(this); }