Пример #1
0
        /// <summary>
        /// Open a new output file.
        /// </summary>
        /// <remarks>Any existing file will be closed.</remarks>
        private void OpenFile()
        {
            //clear the existing file pointer to make sure if we fail, it's gone.
            //we also rely on this to distinguish adding a new file to an existing stream.
            CloseFile(false);

            //increment our session file counter since we're going to open a new file
            m_CurrentSessionFile++;

            //Calculate our candidate file name (with path) based on what we know.
            string fileNamePath = Path.Combine(m_RepositoryFolder, MakeFileName());

            //now double check that the candidate path is unique
            fileNamePath = FileSystemTools.MakeFileNamePathUnique(fileNamePath);

            //we now have a unique file name, create the file.
            FileSystemTools.EnsurePathExists(fileNamePath);
            m_CurrentFile = new FileStream(fileNamePath, FileMode.CreateNew, FileAccess.Write);

            //and open a serializer on it
            m_CurrentSerializer = new GLFWriter(m_CurrentFile, Publisher.SessionSummary, m_CurrentSessionFile, DateTimeOffset.Now);

            //write out every header packet to the stream
            ICachedMessengerPacket[] headerPackets = Publisher.HeaderPackets;
            if (headerPackets != null)
            {
                foreach (ICachedMessengerPacket packet in headerPackets)
                {
                    m_CurrentSerializer.Write(packet);
                }
            }

            //and set a time for us to do our next index update.
            m_FileExpiration = DateTime.Now.AddSeconds(m_MaxLogDurationSeconds);
        }
Пример #2
0
        /// <summary>
        /// Shared logic for creating all streams
        /// </summary>
        public static StreamWriter CreateStream(string fileNamePath)
        {
            FileSystemTools.EnsurePathExists(fileNamePath);

            // Create the stream
            Log.Write(LogMessageSeverity.Verbose, LogCategory, "Creating file to export session data", fileNamePath);
            return(new StreamWriter(File.Create(fileNamePath)));
        }
Пример #3
0
        /// <summary>
        /// Save the package to the specified file name and path, overwriting any existing data
        /// </summary>
        /// <param name="progressMonitors"></param>
        /// <param name="fileNamePath"></param>
        public void Save(ProgressMonitorStack progressMonitors, string fileNamePath)
        {
            if (string.IsNullOrEmpty(fileNamePath))
            {
                throw new ArgumentNullException(nameof(fileNamePath), "Unable to save the current package because no path has been set to save to.");
            }

            //normalize the destination
            fileNamePath = Path.GetFullPath(fileNamePath);

            //make sure the path exists so we can save into it.
            FileSystemTools.EnsurePathExists(fileNamePath);

            lock (m_Lock)
            {
                int steps          = 2;
                int completedSteps = 0;
                using (ProgressMonitor ourMonitor = progressMonitors.NewMonitor(this, "Saving Package", steps))
                {
                    //Do the save (if this fails, we failed)
                    ourMonitor.Update("Saving Package File to Disk", completedSteps++);

                    m_Archive.Dispose(); // ...So we need to dispose and reopen the archive.

                    //check to see if we're saving to the same file we *are*...
                    if (fileNamePath.Equals(m_FileNamePath, StringComparison.OrdinalIgnoreCase) == false)
                    {
                        File.Copy(m_FileNamePath, fileNamePath, true);
                        try
                        {
                            File.Delete(m_FileNamePath);
                        }
                        catch (Exception ex)
                        {
                            if (!Log.SilentMode)
                            {
                                Log.Write(LogMessageSeverity.Error, LogWriteMode.Queued, ex, LogCategory,
                                          "Unable to Delete Package Temporary File due to " + ex.GetType(),
                                          "Unable to delete the temporary working file '{0}'. This means we'll use more disk space than we should but otherwise should not impact the application.",
                                          m_FileNamePath);
                            }
                        }

                        m_FileNamePath = fileNamePath;
                    }

                    ourMonitor.Update("Confirming package contents", completedSteps++);

                    //Since we were successful at saving, this is our new path and we are no longer dirty.
                    m_FileNamePath = fileNamePath;
                    m_Archive      = ZipFile.Open(m_FileNamePath, ZipArchiveMode.Update); // Now we should again be able to read any entry.
                    LoadIndex();
                    IsDirty = false;
                }
            }
        }
Пример #4
0
        /// <summary>
        /// Inheritors should override this method to implement custom initialize functionality.
        /// </summary>
        /// <remarks>This method will be called exactly once before any call to OnFlush or OnWrite is made.
        /// Code in this method is protected by a Thread Lock.
        /// This method is called with the Message Dispatch thread exclusively.</remarks>
        protected override void OnInitialize(IMessengerConfiguration configuration)
        {
            //do our first time initialization
            Caption     = "Standard File Messenger";
            Description = "Messenger implementation that writes messages to files through a buffer.  Supports synchronous and asynchronous messaging.";

            //try to up cast the configuration to our specific configuration type
            var fileConfiguration = (SessionFileConfiguration)configuration;

            //If the max file size is unbounded (zero or less) then we want 1GB.
            m_MaxFileSizeBytes = fileConfiguration.MaxFileSize < 1 ? 1024 : fileConfiguration.MaxFileSize;
            m_MaxFileSizeBytes = m_MaxFileSizeBytes * 1048576;                //the configured value is in MB, we use bytes for faster comparisons

            m_MaxLogDurationSeconds = fileConfiguration.MaxFileDuration * 60; //the configured value is in minutes, we use seconds for consistency

            m_RepositoryMaintenanceEnabled = fileConfiguration.EnableFilePruning;
            m_MaxLocalDiskUsage            = fileConfiguration.MaxLocalDiskUsage;
            m_MaxLocalFileAge = fileConfiguration.MaxLocalFileAge;

            //what are the very best folders for us to use?
            m_RepositoryFolder  = LocalRepository.CalculateRepositoryPath(Publisher.SessionSummary.Product, fileConfiguration.Folder);
            m_SessionLockFolder = Path.Combine(m_RepositoryFolder, SessionLockFolderName);

            //we also have to be sure the path exists now.
            FileSystemTools.EnsurePathExists(m_RepositoryFolder);
            FileSystemTools.EnsurePathExists(m_SessionLockFolder);

            //Since we update the index during a flush, and the index update is about as bad as a flush we look at both together.
            AutoFlush         = true;
            AutoFlushInterval = Math.Min(fileConfiguration.AutoFlushInterval, fileConfiguration.IndexUpdateInterval);

            //If we aren't able to initialize our log folder, throw an exception
            if (string.IsNullOrEmpty(m_RepositoryFolder))
            {
                throw new DirectoryNotFoundException("No log folder could be determined, so the file messenger can't log.");
            }

            ScheduleRepositoryMaintenance(0, 0);

            GetSessionFileLock();
        }