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
Failed SqlConnection with Pooling drags down entire .NET Core MVC App #19735
Comments
@h3smith Can you provide details about the environment? What is the OS and .Net core version that you are using? If you have a sample app we could try out, that would be helpful. |
@saurabh500 I've tested this on Windows 2012 R2 (SQL Server 2012), Docker on OS X (Both SQL Server 2012 and SQL Server on Docker), AWS EC2 (Amazon RDS SQL Server). So a variety of environments. Doesn't seem to be tied to a single configuration. |
The function should not let the exception escape (with |
Same with PoolCreateRequest in System.Data.Odbc |
The exceptions from SqlClient should be surfaced to the user by throwing it as it is happening right now. The exceptions are expected and would need to be surfaced. Even if a It's up to the user to rectify the cause of the exception which could be bad credentials, bad network etc. |
Yes but Same as if you threw an exception in the Main function and didn't catch it. You'll have to route it back in some way. |
@benaadams Thanks for pointing out the code. The Connection Pool for System.Data (used by ODBC and SqlClient) are relying on the ThreadPool handling the exception and returning the thread to the pool. Routing the exception some other way would be a breaking change with respect to how the exceptions are surfaced from the ConnectionPool. The alternate routing is definitely needed for MVC apps where the exception on thread pool may cause the application to crash, however the applications which expect the exceptions to be thrown, will break, especially when comes to interoperability of the app code between .Net Core and Framework. I am working on a Repro and reading through the issues that you have linked to understand what decisions were taken around similar problems. |
At a guess for the e.g. private void PoolCreateRequest(object state)
{
try
{
// ...
}
catch (Exception ex)
{
_resError = ex;
_errorOccurred = true;
}
} Whether it normally gets swallowed on the Framework as a You may want to check e.g. private void WrappedPoolCreateRequest(object state)
{
try
{
PoolCreateRequest(state);
}
catch (Exception ex)
{
_resError = ex;
_errorOccurred = true;
}
} and in .ctor if (Thread.CurrentThread.SynchronizationContext == null)
{
_poolCreateRequest = new WaitCallback(WrappedPoolCreateRequest);
}
else
{
_poolCreateRequest = new WaitCallback(PoolCreateRequest);
} |
I was trying to repro the issue with this simple ASP.NET Core code.
Controller method:
The web app does not crash with wrong password, and browser simply shows this message on screen.
It seems it is already fixed. |
Hello,
Controller method:
|
@saurabh500 We are having this issue in production so it is critical for us. This effectively means we cannot use connection pooling in Core. |
I think the issue is specific to the use case of warming up the connection pool, where the Min Pool Size is set to a non-zero value, and the connections are being populated in the connection pool using the Min Pool Size. |
In case the connection being opened in the
fails, the exception can be handled. However if the connection error occurs when the pool spins up threads to bring up the connection count to Min Pool Size, they lead to an application crash. |
Suppose still exists as a regression at 2.1.300-preview2-008533.
And for an instance, no conection to server, whole app is going down with uncatchable exception
OS: Ubuntu 18.04 |
@EndarValuk What version of SqlClient are you using? |
@saurabh500 your truth. I was using SqlClient 4.4.3. |
When Pooling is enabled on a SqlConnection, and the connection fails (bad password, bad username, database doesn't exist) it will crash the entire .NET Core MVC app running.
For instance, the connection string:
Password=mybadpassword;User Id=api_web_admn;Data Source=127.0.0.1,1433;Initial Catalog=MyDatabase;Integrated Security=False;Min Pool Size=1;Max Pool Size=200;Pooling=true;
produces:
and causes the .NET Core runtime to exit the thread.
Removing Pooling, or Pooling=false, it simply throws an exception and you can handle it.
As it stands now, you can't mitigate and handle a failed connection in .NET Core MVC.
The text was updated successfully, but these errors were encountered: