Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streams: Fix SelectAsync race condition bug #7338

Merged
merged 1 commit into from
Sep 12, 2024

Conversation

Arkatufus
Copy link
Contributor

Fixes #7330

Changes

  • Add decider check inside the PushOne() loop

Notes

Since this is a race condition bug, there is no reliable way to create a regression unit test for this bug.

This is the brute force unit test used to make sure that this fix works as intended:

[Theory]
[Repeat(10000)]
public async Task A_Flow_with_SelectAsync_must_signal_error_at_appropriate_time_from_SelectAsync(int _)
{
    var failurePoint = ThreadLocalRandom.Current.Next(3, 50);
    var output = new List<int>();
    (await Awaiting(async () =>
        {
            await Source.From(Enumerable.Range(1, 500))
                .SelectAsync(100, n =>
                {
                    if (n % failurePoint == 0)
                        return Task.Run<int>(async () =>
                        {
                            await Task.Delay(ThreadLocalRandom.Current.Next(100, 200).Milliseconds());
                            throw new TestException("err2");
                        });

                    return Task.Run(async () =>
                    {
                        await Task.Delay(ThreadLocalRandom.Current.Next(20, 50).Milliseconds());
                        return n;
                    });
                })
                .Select(i =>
                {
                    output.Add(i);
                    return i;
                })
                .RunWith(Sink.Ignore<int>(), Materializer)
                .ShouldCompleteWithin(5.Seconds());
        }).Should().ThrowAsync<AggregateException>())
        .WithInnerExceptionExactly<TestException>()
        .WithMessage("err2");

    output.Count.Should().Be(failurePoint - 1);
}

Copy link
Member

@Aaronontheweb Aaronontheweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - nice catch @Arkatufus @MattiasJakobsson

@Aaronontheweb Aaronontheweb enabled auto-merge (squash) September 12, 2024 14:46
@Aaronontheweb Aaronontheweb merged commit 8e2e11d into akkadotnet:dev Sep 12, 2024
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Item can be handed downstream from a SelectAsync stage even though a earlier item throws a exception
2 participants