示例#1
0
        private Byte[] PublishMessages(Byte[] data, Queue <LogEntry> publishQueue, TimeSpan timeout)
        {
            LogBook logBook = DeserializeLogBook(data);

            logBook.TrimStaleEntries(DateTime.UtcNow - _minMessageAge);
            Int64 logSize = logBook.CalculateLogSize();

            // Start slot timer after deserializing log so deserialization doesn't starve the slot time
            Stopwatch slotTimer = Stopwatch.StartNew();
            DateTime  batchTime = DateTime.UtcNow;

            // Try to exhaust the publish queue but don't keep a write lock forever
            while (publishQueue.Count > 0 && slotTimer.Elapsed < timeout)
            {
                // Check if the next message will fit in the log
                if (logSize + LogEntry.Overhead + publishQueue.Peek().Message.Length > _memoryMappedFile.MaxFileSize)
                {
                    break;
                }

                // Write the entry to the log
                LogEntry entry = publishQueue.Dequeue();
                entry.Id        = ++logBook.LastId;
                entry.Timestamp = batchTime;
                logBook.Entries.Add(entry);

                logSize += LogEntry.Overhead + entry.Message.Length;

                // Skip counting empty messages though, they are skipped on the receiving end anyway
                if (entry.Message.Length == 0)
                {
                    continue;
                }

                Interlocked.Increment(ref _messagesPublished);
            }

            // Flush the updated log to the memory mapped file
            using MemoryStream memoryStream = new MemoryStream((Int32)logSize);
            Serializer.Serialize(memoryStream, logBook);
            return(memoryStream.ToArray());
        }