attempt to fix infinite loop in moment-reference-builder

This commit is contained in:
benbierens 2024-10-18 09:03:19 +02:00
parent 1859994ec6
commit d8a6df5845
No known key found for this signature in database
GPG Key ID: 877D2C2E09A22F3A
2 changed files with 30 additions and 21 deletions

View File

@ -7,6 +7,7 @@ namespace OverwatchTranscript
public interface IFinalizedBucket public interface IFinalizedBucket
{ {
bool IsEmpty { get; } bool IsEmpty { get; }
void Update();
DateTime? SeeTopUtc(); DateTime? SeeTopUtc();
BucketTop? TakeTop(); BucketTop? TakeTop();
} }
@ -28,7 +29,8 @@ namespace OverwatchTranscript
private readonly string bucketFile; private readonly string bucketFile;
private readonly ConcurrentQueue<BucketTop> topQueue = new ConcurrentQueue<BucketTop>(); private readonly ConcurrentQueue<BucketTop> topQueue = new ConcurrentQueue<BucketTop>();
private readonly AutoResetEvent itemDequeued = new AutoResetEvent(false); 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) public EventBucketReader(ILog log, string bucketFile)
{ {
@ -42,34 +44,38 @@ namespace OverwatchTranscript
public bool IsEmpty { get; private set; } 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() public DateTime? SeeTopUtc()
{ {
if (IsEmpty) return null; if (IsEmpty) return null;
while (true) if (topQueue.TryPeek(out BucketTop? top))
{ {
UpdateIsEmpty(); return top.Utc;
if (IsEmpty) return null;
if (topQueue.TryPeek(out BucketTop? top))
{
return top.Utc;
}
} }
return null;
} }
public BucketTop? TakeTop() public BucketTop? TakeTop()
{ {
if (IsEmpty) return null; if (IsEmpty) return null;
if (topQueue.TryDequeue(out BucketTop? top))
while (true)
{ {
UpdateIsEmpty(); itemDequeued.Set();
if (IsEmpty) return null; return top;
if (topQueue.TryDequeue(out BucketTop? top))
{
itemDequeued.Set();
return top;
}
} }
return null;
} }
private void ReadBucket() private void ReadBucket()
@ -85,23 +91,25 @@ namespace OverwatchTranscript
if (top != null) if (top != null)
{ {
topQueue.Enqueue(top); topQueue.Enqueue(top);
itemEnqueued.Set();
} }
else else
{ {
stopping = true; sourceIsEmpty = true;
UpdateIsEmpty();
return; return;
} }
} }
itemDequeued.Reset(); itemDequeued.Reset();
itemDequeued.WaitOne(); itemDequeued.WaitOne(5000);
} }
} }
private void UpdateIsEmpty() private void UpdateIsEmpty()
{ {
var empty = stopping && topQueue.IsEmpty; var allEmpty = sourceIsEmpty && topQueue.IsEmpty;
if (!IsEmpty && empty) if (!IsEmpty && allEmpty)
{ {
File.Delete(bucketFile); File.Delete(bucketFile);
IsEmpty = true; IsEmpty = true;

View File

@ -68,6 +68,7 @@ namespace OverwatchTranscript
{ {
if (bucket.IsEmpty) continue; if (bucket.IsEmpty) continue;
bucket.Update();
var utc = bucket.SeeTopUtc(); var utc = bucket.SeeTopUtc();
if (utc == null) continue; if (utc == null) continue;