Ejemplo n.º 1
0
        /// <inheritdoc />
        public List <StoredFrame> ReadBetween(
            DateTime inclusiveFrom,
            DateTime exclusiveTo
            )
        {
            var frames = ReadFramesFromDb(inclusiveFrom, exclusiveTo);

            var frameGroups = (
                from frame in frames
                group frame by frame.FilePath into frameGroup
                select frameGroup
                ).ToList();

            foreach (var frameGroup in frameGroups)
            {
                lock (TargetFileLocker.GetFileLocker(frameGroup.Key))
                {
                    using (var fs = File.OpenRead(frameGroup.Key))
                    {
                        foreach (var frame in frameGroup.OrderBy(f => f.Offset))
                        {
                            fs.Position = frame.Offset;

                            var compressedBody = new byte[frame.Length];
                            fs.Read(compressedBody, 0, compressedBody.Length);

                            using (var targetStream = new MemoryStream(compressedBody))
                            {
                                using (var decompressionStream = new GZipStream(targetStream, CompressionMode.Decompress))
                                {
                                    using (var sr = new StreamReader(decompressionStream, Encoding.UTF8))
                                    {
                                        var body = sr.ReadToEnd();
                                        frame.AppendBody(body);
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(frames);
        }
Ejemplo n.º 2
0
        /// <inheritdoc />
        protected override void LogCompleteMessage(
            string message
            )
        {
            //zip message...
            byte[] zippedMessage;
            using (var targetStream = new MemoryStream())
            {
                using (var compressionStream = new GZipStream(targetStream, CompressionMode.Compress))
                {
                    using (var sw = new StreamWriter(compressionStream, Encoding.UTF8))
                    {
                        sw.Write(message);
                    }
                }

                zippedMessage = targetStream.ToArray();
            }

            //determine target file...
            var(targetFilePath, targetFolderPath, targetFileName) = _targetController.GetTargetFile();

            //append data
            var offset = 0L;

            lock (TargetFileLocker.GetFileLocker(targetFilePath))
            {
                using (var fs = new FileStream(targetFilePath, FileMode.Append, FileAccess.Write))
                {
                    offset = fs.Position;
                    fs.Write(zippedMessage, 0, zippedMessage.Length);
                    fs.Flush();
                }

                //we should still hold the file lock here for the case of revert
                //otherwise different thread (different SqlServerCollectionSaver)
                //can append their data between append ours and revert ours
                //in that case we will truncate both records and DB-metadata will be completely invalid

                //save metadata to DB
                try
                {
                    _command.Parameters["fileName"].Value = targetFileName.GetFromLast(261);
                    _command.Parameters["offset"].Value   = offset;
                    _command.Parameters["length"].Value   = zippedMessage.Length;
                    _command.ExecuteNonQuery();
                }
                catch (Exception firstException)
                {
                    //shit happens...

                    //try to revert the file to its original state
                    try
                    {
                        using (var fs = new FileStream(targetFilePath, FileMode.Open, FileAccess.ReadWrite))
                        {
                            fs.SetLength(offset);
                        }
                    }
                    catch (Exception secondException)
                    {
                        //reverting fails, this file is unrecoverable
                        //force to switch the file!
                        _targetController.SwitchTargetFile();

                        throw new AggregateException(firstException, secondException);
                    }

                    throw;
                }
            }

            //success
        }