in src/StructuredLogger/BinaryLogger/BinLogReader.cs [59:138]
public void Replay(Stream stream, Progress progress)
{
var gzipStream = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true);
var bufferedStream = new BufferedStream(gzipStream, 32768);
var binaryReader = new BinaryReader(bufferedStream);
int fileFormatVersion = binaryReader.ReadInt32();
OnFileFormatVersionRead?.Invoke(fileFormatVersion);
EnsureFileFormatVersionKnown(fileFormatVersion);
// Use a producer-consumer queue so that IO can happen on one thread
// while processing can happen on another thread decoupled. The speed
// up is from 4.65 to 4.15 seconds.
var queue = new BlockingCollection<BuildEventArgs>(boundedCapacity: 5000);
var processingTask = System.Threading.Tasks.Task.Run(() =>
{
foreach (var args in queue.GetConsumingEnumerable())
{
Dispatch(args);
}
});
int recordsRead = 0;
using var reader = new BuildEventArgsReader(binaryReader, fileFormatVersion);
reader.OnBlobRead += OnBlobRead;
Stopwatch stopwatch = Stopwatch.StartNew();
var streamLength = stream.Length;
while (true)
{
BuildEventArgs instance = null;
try
{
instance = reader.Read();
}
catch (Exception ex)
{
OnException?.Invoke(ex);
}
recordsRead++;
if (instance == null)
{
queue.CompleteAdding();
break;
}
queue.Add(instance);
if (progress != null && recordsRead % 1000 == 0 && stopwatch.ElapsedMilliseconds > 200)
{
stopwatch.Restart();
var streamPosition = stream.Position;
double ratio = (double)streamPosition / streamLength;
progress.Report(ratio);
}
}
processingTask.Wait();
if (fileFormatVersion >= 10)
{
var strings = reader.GetStrings();
if (strings != null && strings.Any())
{
OnStringDictionaryComplete?.Invoke(strings);
}
}
if (progress != null)
{
progress.Report(1.0);
}
}