diff --git a/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs b/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs index 7a901e8d..6229815f 100644 --- a/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs +++ b/src/Microsoft.SqlTools.Hosting/Utility/CommandOptions.cs @@ -79,6 +79,9 @@ namespace Microsoft.SqlTools.Utility case "-enable-sql-authentication-provider": EnableSqlAuthenticationProvider = true; break; + case "-enable-connection-pooling": + EnableConnectionPooling = true; + break; case "-parent-pid": string nextArg = args[++i]; if (Int32.TryParse(nextArg, out int parsedInt)) @@ -179,6 +182,11 @@ namespace Microsoft.SqlTools.Utility /// public bool EnableSqlAuthenticationProvider { get; private set; } = false; + /// + /// Enables connection pooling for all SQL connections, removing feature name identifier from application name to prevent unwanted connection pools. + /// + public bool EnableConnectionPooling { get; private set; } = false; + /// /// The ID of the process that started this service. This is used to check when the parent /// process exits so that the service process can exit at the same time. diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs index bf750e5e..7e7f049d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs @@ -172,6 +172,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection /// public bool EnableSqlAuthenticationProvider { get; set; } + /// + /// Enables connection pooling for all SQL connections, removing feature name identifier from application name to prevent unwanted connection pools. + /// + public static bool EnableConnectionPooling { get; set; } + /// /// Returns a connection queue for given type /// @@ -474,8 +479,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection internal static string GetApplicationNameWithFeature(string applicationName, string featureName) { string appNameWithFeature = applicationName; - - if (!string.IsNullOrWhiteSpace(applicationName) && !string.IsNullOrWhiteSpace(featureName) && !applicationName.EndsWith(featureName)) + // Connection Service will not set custom application name if connection pooling is enabled on service. + if (!EnableConnectionPooling && !string.IsNullOrWhiteSpace(applicationName) && !string.IsNullOrWhiteSpace(featureName) && !applicationName.EndsWith(featureName)) { int azdataStartIndex = applicationName.IndexOf(Constants.DefaultApplicationName); string originalAppName = azdataStartIndex != -1 @@ -671,7 +676,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection try { - connectionInfo.ConnectionDetails.Pooling = false; + if (!EnableConnectionPooling) + { + connectionInfo.ConnectionDetails.Pooling = false; + } // build the connection string from the input parameters string connectionString = BuildConnectionString(connectionInfo.ConnectionDetails); @@ -1086,15 +1094,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection { this.ServiceHost = serviceHost; - if (commandOptions != null && commandOptions.EnableSqlAuthenticationProvider) + if (commandOptions != null) { + if (commandOptions.EnableSqlAuthenticationProvider) + { + // Register SqlAuthenticationProvider with SqlConnection for AAD Interactive (MFA) authentication. + var provider = new AuthenticationProvider(GetAuthenticator(commandOptions)); + SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, provider); - // Register SqlAuthenticationProvider with SqlConnection for AAD Interactive (MFA) authentication. - var provider = new AuthenticationProvider(GetAuthenticator(commandOptions)); - SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, provider); - - this.EnableSqlAuthenticationProvider = true; - Logger.Information("Registering implementation of SQL Authentication provider for 'Active Directory Interactive' authentication mode."); + this.EnableSqlAuthenticationProvider = true; + Logger.Information("Registering implementation of SQL Authentication provider for 'Active Directory Interactive' authentication mode."); + } + if (commandOptions.EnableConnectionPooling) + { + ConnectionService.EnableConnectionPooling = true; + Logger.Information("Connection pooling will be enabled for all SQL connections."); + } } // Register request and event handlers with the Service Host @@ -1586,7 +1601,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection { connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion; } - if (forceDisablePooling) + if (!EnableConnectionPooling && forceDisablePooling) { connectionBuilder.Pooling = false; } @@ -1844,7 +1859,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection bool? originalPooling = connInfo.ConnectionDetails.Pooling; // allow pooling connections for language service feature to improve intellisense connection retention and performance. - bool shouldForceDisablePooling = featureName != Constants.LanguageServiceFeature; + bool shouldForceDisablePooling = !EnableConnectionPooling && featureName != Constants.LanguageServiceFeature; // increase the connection and command timeout to at least 30 seconds and and build connection string connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);