Skip to content

Commit

Permalink
Query: Remove race condition in split query (#21301)
Browse files Browse the repository at this point in the history
Resolves #21296

Issue: `TaskAwaiter(new Task[] { PopulateSplitCollectionInclude(), PopulateSplitCollectionInclude() })` rather than creating task array and passing to method it also started executing them causing threading issue.
Fix: `TaskAwaiter(new Func<Task>[] { () => PopulateSplitCollectionInclude(), () => PopulateSplitCollectionInclude() })` creates the actual task only when we are ready to await them.
  • Loading branch information
smitpatel committed Jun 17, 2020
1 parent 5b7f684 commit 38e2c3d
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ public LambdaExpression ProcessShaper(

if (_isAsync)
{
var tasks = Expression.NewArrayInit(typeof(Task), _collectionPopulatingExpressions);
var tasks = Expression.NewArrayInit(typeof(Func<Task>), _collectionPopulatingExpressions.Select(
e => Expression.Lambda<Func<Task>>(e)));
relatedDataLoaders = Expression.Lambda<Func<QueryContext, IExecutionStrategy, SplitQueryResultCoordinator, Task>>(
Expression.Call(_taskAwaiterMethodInfo, tasks),
QueryCompilationContext.QueryContextParameter,
Expand Down Expand Up @@ -1727,11 +1728,11 @@ async Task<bool> InitializeReaderAsync(DbContext _, bool result, CancellationTok
dataReaderContext.HasNext = false;
}

private static async Task TaskAwaiter(Task[] tasks)
private static async Task TaskAwaiter(Func<Task>[] taskFactories)
{
for (var i = 0; i < tasks.Length; i++)
for (var i = 0; i < taskFactories.Length; i++)
{
await tasks[i].ConfigureAwait(false);
await taskFactories[i]().ConfigureAwait(false);
}
}

Expand Down
Loading

0 comments on commit 38e2c3d

Please sign in to comment.