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

NpgsqlConnection.WaitAsync(): Npgsql.NpgsqlException (0x80004005): Received backend message RowDescription while expecting ParseCompleteMessage. Please file a bug. #2506

Open
worldleaderpretend opened this issue Jun 26, 2019 · 2 comments

Comments

@worldleaderpretend
Copy link

commented Jun 26, 2019

I ran into this a few times while using a listener. I finally traced it back to a race condition with the cancellation token. Seems if a cancelled token gets sent to WaitAsync(), then the next command fails with this error. Here's some sample code (TableA is a non-existent). I tested with 4.0.7:

using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
    connection.Open();

    using (NpgsqlCommand command = new NpgsqlCommand("LISTEN TableA", connection))
    {
        command.ExecuteNonQuery();
    }

    using (CancellationTokenSource tokenSource = new CancellationTokenSource())
    {
        try
        {
            tokenSource.Cancel();

            connection.WaitAsync(tokenSource.Token).Wait();
        }
        catch (AggregateException ex) when (ex.InnerExceptions.Any(x => (x is TaskCanceledException)))
        {
        }
    }

    using (NpgsqlCommand command = new NpgsqlCommand("SELECT NULL", connection))
    {
        command.ExecuteNonQuery();
    }
}

I found that I can workaround this by locking the call to WaitAsync to prevent the cancel occurring before the async returns. So it appears everything is good to go if it makes it to the first await, It basically turns it into the following code, which works fine:

using (NpgsqlConnection connection = new NpgsqlConnection(connectionString))
{
    connection.Open();

    using (NpgsqlCommand command = new NpgsqlCommand("LISTEN TableA", connection))
    {
        command.ExecuteNonQuery();
    }

    using (CancellationTokenSource tokenSource = new CancellationTokenSource())
    {
        try
        {
            Task connectionWait = connection.WaitAsync(tokenSource.Token);

            tokenSource.Cancel();

            connectionWait.Wait();
        }
        catch (AggregateException ex) when (ex.InnerExceptions.Any(x => (x is TaskCanceledException)))
        {
        }
    }

    using (NpgsqlCommand command = new NpgsqlCommand("SELECT NULL", connection))
    {
        command.ExecuteNonQuery();
    }
}


@roji roji added this to the 4.0.8 milestone Jun 26, 2019

@roji roji added the bug label Jun 26, 2019

@roji roji self-assigned this Jun 26, 2019

roji added a commit to roji/Npgsql that referenced this issue Jun 26, 2019

Check cancellation token at start of WaitAsync()
Otherwise passing a cancelled token makes WaitAsync() crash.
Note that a race condition still exists if the token is cancelled
after our check but before WaitAsync starts its job.

Fixes npgsql#2506

roji added a commit to roji/Npgsql that referenced this issue Jun 26, 2019

Check cancellation token at start of WaitAsync()
Otherwise passing a cancelled token makes WaitAsync() crash.
Note that a race condition still exists if the token is cancelled
after our check but before WaitAsync starts its job.

Fixes npgsql#2506

roji added a commit to roji/Npgsql that referenced this issue Jun 29, 2019

Check cancellation token at start of WaitAsync()
Otherwise passing a cancelled token makes WaitAsync() crash.
Note that a race condition still exists if the token is cancelled
after our check but before WaitAsync starts its job.

Fixes npgsql#2506

roji added a commit that referenced this issue Jun 29, 2019

Check cancellation token at start of WaitAsync()
Otherwise passing a cancelled token makes WaitAsync() crash.
Note that a race condition still exists if the token is cancelled
after our check but before WaitAsync starts its job.

Fixes #2506
@austindrenski

This comment has been minimized.

Copy link
Member

commented Jun 30, 2019

@roji Looks like this was meant to close with #2507, but wasn't because f5bbc74 wasn't merged with our default branch (e.g. dev).

@roji

This comment has been minimized.

Copy link
Member

commented Jul 1, 2019

@austindrenski was keeping this open until #2443 is merged, which fixes this in dev.

@roji roji reopened this Jul 1, 2019

@YohDeadfall YohDeadfall modified the milestones: 4.0.8, 4.0.9 Jul 18, 2019

@roji roji modified the milestones: 4.0.9, 4.0.10 Aug 14, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.