Exemplo n.º 1
0
        // Monitors for roll-over notifications
        private void m_rolloverWatcher_Elapsed(object sender, ElapsedEventArgs e)
        {
            // Don't start another rollover activity if one is already in progress...
            if (Monitor.TryEnter(m_watcherLock))
            {
                try
                {
                    // Read the inter-process communications file for changes in roll-over state
                    if ((object)m_archiveFile != null && (object)m_archiveFile.IntercomFile != null && m_archiveFile.IntercomFile.IsOpen)
                    {
                        m_archiveFile.IntercomFile.Load();
                        IntercomRecord record = m_archiveFile.IntercomFile.Read(1);

                        if ((object)record != null)
                        {
                            // Pause processing
                            if (record.RolloverInProgress && m_archiveFile.IsOpen)
                            {
                                // Notify internal archive file components about the pending rollover
                                m_archiveFile.RolloverWaitHandle.Reset();

                                // Raise roll-over start event (sets m_rolloverInProgress flag)
                                m_archiveFile.OnRolloverStart();

                                // Wait for pending to reads to yield
                                m_archiveFile.WaitForReadersRelease();

                                // Close the active archive file stream so it can be rolled-over
                                m_archiveFile.CloseStream();
                            }

                            // Resume processing
                            if (!record.RolloverInProgress && !m_archiveFile.IsOpen)
                            {
                                // Open new active archive file stream
                                m_archiveFile.OpenStream();

                                // Raise roll-over complete event (resets m_rolloverInProgress flag)
                                m_archiveFile.OnRolloverComplete();

                                // Notify waiting internal archive components that rollover is complete
                                m_archiveFile.RolloverWaitHandle.Set();
                            }
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    OnDataReadException(new InvalidOperationException("Exception encountered during roll-over processing: " + ex.Message, ex));
                }
                finally
                {
                    Monitor.Exit(m_watcherLock);
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Opens the <see cref="ArchiveFile"/> for use.
        /// </summary>
        /// <exception cref="InvalidOperationException">One or all of the <see cref="StateFile"/>, <see cref="IntercomFile"/> or <see cref="MetadataFile"/> properties are not set.</exception>
        public void Open()
        {
            if (!IsOpen)
            {
                // Check for the existence of dependencies.
                if ((object)m_stateFile == null || (object)m_intercomFile == null || (object)m_metadataFile == null)
                    throw (new InvalidOperationException("One or more of the dependency files are not specified."));

                // Validate file type against its name.
                if (Path.GetExtension(m_fileName).ToNonNullString().ToLower() == StandbyFileExtension)
                    m_fileType = ArchiveFileType.Standby;
                else if (Regex.IsMatch(m_fileName.ToLower(), string.Format(".+_.+_to_.+\\{0}$", FileExtension)))
                    m_fileType = ArchiveFileType.Historic;
                else
                    m_fileType = ArchiveFileType.Active;

                // Get the absolute path for the file name.
                m_fileName = FilePath.GetAbsolutePath(m_fileName);

                // Create the directory if it does not exist.
                if (!Directory.Exists(FilePath.GetDirectoryName(m_fileName)))
                    Directory.CreateDirectory(FilePath.GetDirectoryName(m_fileName));

                // Validate a roll-over is not in progress when opening archive as read-only
                if (m_fileType == ArchiveFileType.Active && m_fileAccessMode == FileAccess.Read)
                {
                    // Open intercom file if closed.
                    if (!m_intercomFile.IsOpen)
                        m_intercomFile.Open();

                    m_intercomFile.Load();
                    IntercomRecord record = m_intercomFile.Read(1);
                    int waitCount = 0;

                    while ((object)record != null && record.RolloverInProgress && waitCount < 30)
                    {
                        Thread.Sleep(1000);
                        m_intercomFile.Load();
                        record = m_intercomFile.Read(1);
                        waitCount++;
                    }
                }

                OpenStream();

                // Open state file if closed.
                if (!m_stateFile.IsOpen)
                    m_stateFile.Open();

                // Open intercom file if closed.
                if (!m_intercomFile.IsOpen)
                    m_intercomFile.Open();

                // Open metadata file if closed.
                if (!m_metadataFile.IsOpen)
                    m_metadataFile.Open();

                // Don't proceed further for standby and historic files.
                if (m_fileType != ArchiveFileType.Active)
                    return;

                // Start internal process queues.
                m_currentDataQueue.Start();
                m_historicDataQueue.Start();
                m_outOfSequenceDataQueue.Start();

                // Create data block lookup list.
                if (m_stateFile.RecordsInMemory > 0)
                    m_dataBlocks = new List<ArchiveDataBlock>(new ArchiveDataBlock[m_stateFile.RecordsInMemory]);
                else
                    m_dataBlocks = new List<ArchiveDataBlock>(new ArchiveDataBlock[m_stateFile.RecordsOnDisk]);

                // Validate the dependency files.
                SyncStateFile(null);

                if (m_intercomFile.FileAccessMode != FileAccess.Read)
                {
                    // Ensure that "rollover in progress" is not set.
                    IntercomRecord system = m_intercomFile.Read(1);

                    if ((object)system == null)
                        system = new IntercomRecord(1);

                    system.RolloverInProgress = false;
                    m_intercomFile.Write(1, system);
                }

                // Start the memory conservation process.
                if (m_conserveMemory)
                {
                    m_conserveMemoryTimer.Interval = DataBlockCheckInterval;
                    m_conserveMemoryTimer.Start();
                }

                if (m_fileType == ArchiveFileType.Active)
                {
                    // Start preparing the list of historic files.
                    m_buildHistoricFileListThread = new Thread(BuildHistoricFileList);
                    m_buildHistoricFileListThread.Priority = ThreadPriority.Lowest;
                    m_buildHistoricFileListThread.Start();

                    // Start file watchers to monitor file system changes.
                    if (m_monitorNewArchiveFiles)
                    {
                        if ((object)m_currentLocationFileWatcher != null)
                        {
                            m_currentLocationFileWatcher.Filter = HistoricFilesSearchPattern;
                            m_currentLocationFileWatcher.Path = FilePath.GetDirectoryName(m_fileName);
                            m_currentLocationFileWatcher.EnableRaisingEvents = true;
                        }

                        if (Directory.Exists(m_archiveOffloadLocation) && (object)m_offloadLocationFileWatcher != null)
                        {
                            m_offloadLocationFileWatcher.Filter = HistoricFilesSearchPattern;
                            m_offloadLocationFileWatcher.Path = m_archiveOffloadLocation;
                            m_offloadLocationFileWatcher.EnableRaisingEvents = true;
                        }
                    }
                }
            }
        }