Skip to content

Commit

Permalink
Do not fail on disposed timer
Browse files Browse the repository at this point in the history
When we have a race condition and timer becomes disposed, the other thread may try to access timer and received ObjectDisposedException. That's why we set timer reference to null before disposing it, and make timer nullable. This is not 100% thread safe code, but want to test how it will behave.
  • Loading branch information
yaroslav-tykhonchuk committed Dec 15, 2023
1 parent 3dce890 commit 2d48b2c
Showing 1 changed file with 19 additions and 8 deletions.
27 changes: 19 additions & 8 deletions AzureBatchQueue/TimerBatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ internal class TimerBatch<T>
readonly ILogger logger;
readonly ConcurrentDictionary<string, BatchItem<T>> items;

readonly Timer timer;
Timer? timer;
BatchCompletedResult? completedResult;

public TimerBatch(BatchQueue<T> batchQueue, QueueMessage<T[]> msg, int maxDequeueCount, ILogger logger)
Expand All @@ -36,7 +36,7 @@ async Task Flush()
{
try
{
await timer.DisposeAsync();
DisposeTimer();

await DoFlush();
}
Expand All @@ -57,6 +57,9 @@ async Task Flush()

async Task DoFlush()
{
if (completedResult != null)
return;

if (items.IsEmpty)
{
completedResult = BatchCompletedResult.FullyProcessed;
Expand All @@ -77,6 +80,16 @@ async Task DoFlush()
}
}

/// <summary>
/// Set timer reference to null, so that call to timer in Complete() will not throw ObjectDisposedException
/// </summary>
void DisposeTimer()
{
var timerCopy = timer;
timer = null;
timerCopy.Dispose();

Check warning on line 90 in AzureBatchQueue/TimerBatch.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 90 in AzureBatchQueue/TimerBatch.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 90 in AzureBatchQueue/TimerBatch.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 90 in AzureBatchQueue/TimerBatch.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.
}

QueueMessage<T[]> Message()
{
var notCompletedItems = items.Values.Select(x => x.Item).ToArray();
Expand All @@ -93,13 +106,11 @@ public BatchItemCompleteResult Complete(string itemId)
if (!res)
throw new ItemNotFoundException(itemId);

if (items.IsEmpty)
{
timer.Change(TimeSpan.Zero, Timeout.InfiniteTimeSpan);
return BatchItemCompleteResult.BatchFullyProcessed;
}
if (!items.IsEmpty)
return BatchItemCompleteResult.Completed;

return BatchItemCompleteResult.Completed;
timer?.Change(TimeSpan.Zero, Timeout.InfiniteTimeSpan);
return BatchItemCompleteResult.BatchFullyProcessed;
}

public IEnumerable<BatchItem<T>> Unpack()
Expand Down

0 comments on commit 2d48b2c

Please sign in to comment.