Skip to content

Commit

Permalink
Fix race condition in BatchBlock's handling of completion (#38651)
Browse files Browse the repository at this point in the history
When a BatchBlock is marked for completion, it will no longer consume postponed messages.  But the BatchesNeedProcessing method, which factors in the number of postponed messages, is accidentally ignoring the _decliningPermanently flag that indicates completion was requested.  As a result, with just the right sequence of operations, the BatchBlock can get stuck in a state where it sees postponed messages and queues a task to process them, but that task then sees that it's declining permanently and so doesn't touch any of the postponed messages, and then upon checking to see if it can complete, sees there are postponed messages, and loops again, resulting in a potentially infinite asynchronous loop.  The fix is just to check _decliningPermanently in BatchesNeedProcessing when considering postponed messages.
  • Loading branch information
stephentoub authored Jul 3, 2020
1 parent c3ab1cf commit 67c8134
Showing 1 changed file with 11 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -587,9 +587,17 @@ private bool BatchesNeedProcessing

if (_nonGreedyState != null)
{
// We can make a triggered batch using postponed messages
if (_nonGreedyState.AcceptFewerThanBatchSize &&
(_messages.Count > 0 || (_nonGreedyState.PostponedMessages.Count > 0 && boundedCapacityAvailable > 0)))
// If a batch was triggered and we have any messages, we can create a batch from what we already have.
if (_nonGreedyState.AcceptFewerThanBatchSize && _messages.Count > 0)
return true;

// At this point, to make a batch we'll need to consume postponed messages, but we can't do
// that if we're declining all future messages.
if (_decliningPermanently)
return false;

// If a batch was triggered and there are any postponed messages to retrieve and there's room available, try.
if (_nonGreedyState.AcceptFewerThanBatchSize && _nonGreedyState.PostponedMessages.Count > 0 && boundedCapacityAvailable > 0)
return true;

if (_dataflowBlockOptions.Greedy)
Expand Down

0 comments on commit 67c8134

Please sign in to comment.