internal void RemoveLogReader(ulong startingRecordPosition) { FabricEvents.Events.LogManager( this.Tracer.Type, "RemoveLogReader: Removing Log Reader with StartingRecordPosition: " + startingRecordPosition); lock (this.readersLock) { LogReaderRange readerRange; for (var i = 0; i < this.logReaderRanges.Count; i++) { readerRange = this.logReaderRanges[i]; if (readerRange.StartingRecordPosition == startingRecordPosition) { if (readerRange.Release() > 0) { return; } this.logReaderRanges.RemoveAt(i); if (i == 0) { this.earliestLogReader = (this.logReaderRanges.Count > 0) ? this.logReaderRanges[0] : LogReaderRange.DefaultLogReaderRange; } // check if removing this reader could help in completing the pending log head truncation if (this.pendingLogHeadTruncationContext != null && this.earliestLogReader.StartingRecordPosition >= this.pendingLogHeadTruncationContext.ProposedPosition) { this.LogHeadRecordPosition = this.pendingLogHeadTruncationContext.ProposedPosition; FabricEvents.Events.LogManager( this.Tracer.Type, "RemoveLogReader: Initiating PerformLogHeadTruncation head position: " + this.LogHeadRecordPosition); var localpendingLogHeadTruncationContext = this.pendingLogHeadTruncationContext; Task.Factory.StartNew(this.PerformLogHeadTruncation, localpendingLogHeadTruncationContext) .IgnoreExceptionVoid(); this.pendingLogHeadTruncationContext = null; } return; } } } Utility.CodingError("Code should never have come here: RemoveLogReader"); }
protected LogManager( string baseLogFileAlias, IncomingBytesRateCounterWriter incomingBytesRateCounter, LogFlushBytesRateCounterWriter logFlushBytesRateCounter, AvgBytesPerFlushCounterWriter bytesPerFlushCounterWriter, AvgFlushLatencyCounterWriter avgFlushLatencyCounterWriter, AvgSerializationLatencyCounterWriter avgSerializationLatencyCounterWriter) { this.BaseLogFileAlias = baseLogFileAlias; this.CurrentLogFileAlias = this.BaseLogFileAlias; this.LogicalLog = null; this.IsDisposed = false; this.LogHeadRecordPosition = 0; this.PhysicalLogWriter = null; this.logReaderRanges = new List <LogReaderRange>(); this.earliestLogReader = LogReaderRange.DefaultLogReaderRange; this.pendingLogHeadTruncationContext = null; this.IncomingBytesRateCounterWriter = incomingBytesRateCounter; this.LogFlushBytesRateCounterWriter = logFlushBytesRateCounter; this.AvgFlushLatencyCounterWriter = avgFlushLatencyCounterWriter; this.AvgSerializationLatencyCounterWriter = avgSerializationLatencyCounterWriter; this.BytesPerFlushCounterWriter = bytesPerFlushCounterWriter; }
internal Task ProcessLogHeadTruncationAsync(TruncateHeadLogRecord truncateHeadRecord) { var tcs = new TaskCompletionSource <object>(); var context = new PendingLogHeadTruncationContext( tcs, truncateHeadRecord); lock (this.readersLock) { if (this.earliestLogReader.StartingRecordPosition < truncateHeadRecord.HeadRecord.RecordPosition) { Utility.Assert( this.pendingLogHeadTruncationContext == null, "Pending Log Head Truncation should be null"); this.pendingLogHeadTruncationContext = context; FabricEvents.Events.LogManager( this.Tracer.Type, "ProcessLogHeadTruncationAsync: Could not truncate log head immediately due to reader: " + this.earliestLogReader.ReaderName); return(tcs.Task); } else { this.LogHeadRecordPosition = truncateHeadRecord.HeadRecord.RecordPosition; FabricEvents.Events.LogManager( this.Tracer.Type, "ProcessLogHeadTruncationAsync: Initiating log head truncation to position: " + this.LogHeadRecordPosition); Task.Factory.StartNew(this.PerformLogHeadTruncation, context).IgnoreExceptionVoid(); return(tcs.Task); } } }