Logs the rollover process so that it can be properly finished in the event of a power outage or process crash
Example #1
0
        /// <summary>
        /// Creates a new <see cref="RolloverLog"/>
        /// </summary>
        /// <param name="settings">the settings</param>
        /// <param name="list">the list</param>
        public RolloverLog(RolloverLogSettings settings, ArchiveList list)
        {
            m_settings = settings.CloneReadonly();
            m_settings.Validate();

            if (settings.IsFileBacked)
            {
                foreach (var logFile in Directory.GetFiles(settings.LogPath, settings.SearchPattern))
                {
                    var log = new RolloverLogFile(logFile);
                    if (log.IsValid)
                    {
                        log.Recover(list);
                    }
                    else
                    {
                        log.Delete();
                    }
                }
            }
        }
        /// <summary>
        /// Creates a new <see cref="RolloverLog"/>
        /// </summary>
        /// <param name="settings">the settings</param>
        /// <param name="list">the list</param>
        public RolloverLog(RolloverLogSettings settings, ArchiveList list)
        {
            m_settings = settings.CloneReadonly();
            m_settings.Validate();

            if (settings.IsFileBacked)
            {
                foreach (var logFile in Directory.GetFiles(settings.LogPath, settings.SearchPattern))
                {
                    var log = new RolloverLogFile(logFile);
                    if (log.IsValid)
                    {
                        log.Recover(list);
                    }
                    else
                    {
                        log.Delete();
                    }
                }
            }
        }
Example #3
0
        private void OnExecute(object sender, EventArgs <ScheduledTaskRunningReason> e)
        {
            //The worker can be disposed either via the Stop() method or
            //the Dispose() method.  If via the dispose method, then
            //don't do any cleanup.
            if (m_disposed && e.Argument == ScheduledTaskRunningReason.Disposing)
            {
                return;
            }

            //go ahead and schedule the next rollover since nothing
            //will happen until this function exits anyway.
            //if the task is disposing, the following line does nothing.
            m_rolloverTask.Start(m_settings.ExecuteTimer);

            lock (m_syncRoot)
            {
                if (m_disposed)
                {
                    return;
                }

                using (ArchiveListSnapshot <TKey, TValue> resource = m_archiveList.CreateNewClientResources())
                {
                    resource.UpdateSnapshot();

                    List <ArchiveTableSummary <TKey, TValue> > list = new List <ArchiveTableSummary <TKey, TValue> >();
                    List <Guid> listIds = new List <Guid>();

                    for (int x = 0; x < resource.Tables.Length; x++)
                    {
                        ArchiveTableSummary <TKey, TValue> table = resource.Tables[x];

                        if (table.SortedTreeTable.BaseFile.Snapshot.Header.Flags.Contains(m_settings.MatchFlag) && table.SortedTreeTable.BaseFile.Snapshot.Header.Flags.Contains(FileFlags.IntermediateFile))
                        {
                            list.Add(table);
                            listIds.Add(table.FileId);
                        }
                        else
                        {
                            resource.Tables[x] = null;
                        }
                    }

                    bool shouldRollover = list.Count >= m_settings.CombineOnFileCount;

                    long size = 0;

                    for (int x = 0; x < list.Count; x++)
                    {
                        size += list[x].SortedTreeTable.BaseFile.ArchiveSize;
                        if (size > m_settings.CombineOnFileSize)
                        {
                            if (x != list.Count - 1)//If not the last entry
                            {
                                list.RemoveRange(x + 1, list.Count - x - 1);
                            }
                            break;
                        }
                    }
                    if (size > m_settings.CombineOnFileSize)
                    {
                        shouldRollover = true;
                    }

                    if (shouldRollover)
                    {
                        TKey startKey = new TKey();
                        TKey endKey   = new TKey();
                        startKey.SetMax();
                        endKey.SetMin();

                        foreach (Guid fileId in listIds)
                        {
                            ArchiveTableSummary <TKey, TValue> table = resource.TryGetFile(fileId);
                            if (table is null)
                            {
                                throw new Exception("File not found");
                            }

                            if (!table.IsEmpty)
                            {
                                if (startKey.IsGreaterThan(table.FirstKey))
                                {
                                    table.FirstKey.CopyTo(startKey);
                                }
                                if (endKey.IsLessThan(table.LastKey))
                                {
                                    table.LastKey.CopyTo(endKey);
                                }
                            }
                        }

                        RolloverLogFile logFile = null;

                        Action <Guid> createLog = (x) =>
                        {
                            logFile = m_rolloverLog.Create(listIds, x);
                        };

                        using (UnionReader <TKey, TValue> reader = new UnionReader <TKey, TValue>(list))
                        {
                            SortedTreeTable <TKey, TValue> dest = m_createNextStageFile.CreateArchiveFile(startKey, endKey, size, reader, createLog);

                            resource.Dispose();

                            using (ArchiveListEditor <TKey, TValue> edit = m_archiveList.AcquireEditLock())
                            {
                                //Add the newly created file.
                                edit.Add(dest);

                                foreach (ArchiveTableSummary <TKey, TValue> table in list)
                                {
                                    edit.TryRemoveAndDelete(table.FileId);
                                }
                            }
                        }

                        if (logFile != null)
                        {
                            logFile.Delete();
                        }
                    }

                    resource.Dispose();
                }

                m_rolloverComplete.Set();
            }
        }