umbraco / Umbraco-CMS

Umbraco is a free and open source .NET content management system helping you deliver delightful digital experiences.
https://umbraco.com
MIT License
4.49k stars 2.69k forks source link

Umbraco no longer waits until MSSQL is available #14968

Closed Nuklon closed 1 year ago

Nuklon commented 1 year ago

Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)

12.2

Bug summary

I don't know when this started, but it at least happens in 12.2. Umbraco doesn't wait for MSSQL to start: The process was terminated due to an unhandled exception.

Exception Info: Microsoft.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
 ---> System.ComponentModel.Win32Exception (2): The system cannot find the file specified.
   at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.Connect(ServerInfo serverInfo, SqlInternalConnectionTds connHandler, Boolean ignoreSniOpenTimeout, Int64 timerExpire, SqlConnectionString connectionOptions, Boolean withFailover)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.AttemptOneLogin(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean ignoreSniOpenTimeout, TimeoutTimer timeout, Boolean withFailover)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.LoginNoFailover(ServerInfo serverInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString connectionOptions, SqlCredential credential, TimeoutTimer timeout)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds.OpenLoginEnlist(TimeoutTimer timeout, SqlConnectionString connectionOptions, SqlCredential credential, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance)
   at Microsoft.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken, DbConnectionPool pool)
   at Microsoft.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
   at Microsoft.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
   at Microsoft.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
   at Umbraco.Cms.Persistence.SqlServer.Services.SqlServerDatabaseCreator.Create(String connectionString)
   at Umbraco.Cms.Infrastructure.Persistence.DbProviderFactoryCreator.CreateDatabase(String providerName, String connectionString)
   at Umbraco.Cms.Infrastructure.Install.UnattendedInstaller.HandleAsync(RuntimeUnattendedInstallNotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.INotificationAsyncHandler`1.HandleAsync(IEnumerable`1 notifications, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishCoreAsync[TNotification](IEnumerable`1 allHandlers, IEnumerable`1 notifications, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.NotificationAsyncHandlerWrapperImpl`1.HandleAsync[TNotification,TNotificationHandler](IEnumerable`1 notifications, CancellationToken cancellationToken, ServiceFactory serviceFactory, Func`4 publish)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishNotificationsAsync[TNotification,TNotificationHandler](IEnumerable`1 notifications, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishAsync[TNotification,TNotificationHandler](IEnumerable`1 notifications, CancellationToken cancellationToken)
   at Umbraco.Cms.Core.Events.EventAggregator.PublishAsync[TNotification](TNotification notification, CancellationToken cancellationToken)
   at Umbraco.Cms.Infrastructure.Runtime.CoreRuntime.StartAsync(CancellationToken cancellationToken, Boolean isRestarting)
   at Umbraco.Cms.Infrastructure.Runtime.CoreRuntime.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
   at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)

Specifics

No response

Steps to reproduce

Start Umbraco while not having MSSQL running

Expected result / actual result

Crash

github-actions[bot] commented 1 year ago

Hi there @Nuklon!

Firstly, a big thank you for raising this issue. Every piece of feedback we receive helps us to make Umbraco better.

We really appreciate your patience while we wait for our team to have a look at this but we wanted to let you know that we see this and share with you the plan for what comes next.

We wish we could work with everyone directly and assess your issue immediately but we're in the fortunate position of having lots of contributions to work with and only a few humans who are able to do it. We are making progress though and in the meantime, we will keep you in the loop and let you know when we have any questions.

Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face:

Zeegaan commented 1 year ago

Heyo πŸ‘‹ I might be misunderstanding something here, but I'm unsure what the issue is. We cannot connect to a non-running database. 😁 Could you give me some exact steps to what you're doing here, and what you expect to happen? πŸ™

Nuklon commented 1 year ago

Iirc Umbraco used to wait until it was available? Now it just crashes on startup. I'd like Umbraco to wait.

Zeegaan commented 1 year ago

Wait how? I'm still not sure what the issue is here 😁 How would you test this?

Nuklon commented 1 year ago

Wait how? I'm still not sure what the issue is here 😁 How would you test this?

The issue is that Umbraco crashes on startup. Just check if the connection works? If it doesn't, try again for a couple of minutes or something?

Zeegaan commented 1 year ago

Ah okay, so if I'm understanding correctly here, the scenario you would like to work is the following:

Nuklon commented 1 year ago

It's more like this:

So now I have to restart Umbraco. Instead, it could check if the connection works. If it doesn't, wait until it becomes available. I'm pretty sure it used to work like that before, but perhaps I'm misremembering.

Zeegaan commented 1 year ago

Thanks for the clarification, I will need to investigate if this ever worked, and then take it up with the team on how to go about this πŸ‘ As it is potato holiday in DenmarkπŸ₯” there will be a little wait time 😁

Zeegaan commented 1 year ago

Coming back, it seems like you could set the connect timeout in your connection string, for example Connect Timeout=300 , hope that helps 🀞