From d8a6df584566eeae8059e64708002f184c98c586 Mon Sep 17 00:00:00 2001 From: benbierens Date: Fri, 18 Oct 2024 09:03:19 +0200 Subject: [PATCH] attempt to fix infinite loop in moment-reference-builder --- .../OverwatchTranscript/EventBucketReader.cs | 50 +++++++++++-------- .../MomentReferenceBuilder.cs | 1 + 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Framework/OverwatchTranscript/EventBucketReader.cs b/Framework/OverwatchTranscript/EventBucketReader.cs index 3fec41d8..ebc915cc 100644 --- a/Framework/OverwatchTranscript/EventBucketReader.cs +++ b/Framework/OverwatchTranscript/EventBucketReader.cs @@ -7,6 +7,7 @@ namespace OverwatchTranscript public interface IFinalizedBucket { bool IsEmpty { get; } + void Update(); DateTime? SeeTopUtc(); BucketTop? TakeTop(); } @@ -28,7 +29,8 @@ namespace OverwatchTranscript private readonly string bucketFile; private readonly ConcurrentQueue topQueue = new ConcurrentQueue(); private readonly AutoResetEvent itemDequeued = new AutoResetEvent(false); - private bool stopping; + private readonly AutoResetEvent itemEnqueued = new AutoResetEvent(false); + private bool sourceIsEmpty; public EventBucketReader(ILog log, string bucketFile) { @@ -42,34 +44,38 @@ namespace OverwatchTranscript public bool IsEmpty { get; private set; } + public void Update() + { + if (IsEmpty) return; + while (topQueue.Count == 0) + { + UpdateIsEmpty(); + if (IsEmpty) return; + + itemDequeued.Set(); + itemEnqueued.WaitOne(200); + } + } + public DateTime? SeeTopUtc() { if (IsEmpty) return null; - while (true) + if (topQueue.TryPeek(out BucketTop? top)) { - UpdateIsEmpty(); - if (IsEmpty) return null; - if (topQueue.TryPeek(out BucketTop? top)) - { - return top.Utc; - } + return top.Utc; } + return null; } public BucketTop? TakeTop() { if (IsEmpty) return null; - - while (true) + if (topQueue.TryDequeue(out BucketTop? top)) { - UpdateIsEmpty(); - if (IsEmpty) return null; - if (topQueue.TryDequeue(out BucketTop? top)) - { - itemDequeued.Set(); - return top; - } + itemDequeued.Set(); + return top; } + return null; } private void ReadBucket() @@ -85,23 +91,25 @@ namespace OverwatchTranscript if (top != null) { topQueue.Enqueue(top); + itemEnqueued.Set(); } else { - stopping = true; + sourceIsEmpty = true; + UpdateIsEmpty(); return; } } itemDequeued.Reset(); - itemDequeued.WaitOne(); + itemDequeued.WaitOne(5000); } } private void UpdateIsEmpty() { - var empty = stopping && topQueue.IsEmpty; - if (!IsEmpty && empty) + var allEmpty = sourceIsEmpty && topQueue.IsEmpty; + if (!IsEmpty && allEmpty) { File.Delete(bucketFile); IsEmpty = true; diff --git a/Framework/OverwatchTranscript/MomentReferenceBuilder.cs b/Framework/OverwatchTranscript/MomentReferenceBuilder.cs index 616ebab6..f8a7c790 100644 --- a/Framework/OverwatchTranscript/MomentReferenceBuilder.cs +++ b/Framework/OverwatchTranscript/MomentReferenceBuilder.cs @@ -68,6 +68,7 @@ namespace OverwatchTranscript { if (bucket.IsEmpty) continue; + bucket.Update(); var utc = bucket.SeeTopUtc(); if (utc == null) continue;