Support enabling connection pooling (#2127)

This commit is contained in:
Cheena Malhotra
2023-07-06 20:46:53 -07:00
committed by GitHub
parent 4c4d6584b3
commit 226b30ffbd
2 changed files with 35 additions and 12 deletions

View File

@@ -79,6 +79,9 @@ namespace Microsoft.SqlTools.Utility
case "-enable-sql-authentication-provider": case "-enable-sql-authentication-provider":
EnableSqlAuthenticationProvider = true; EnableSqlAuthenticationProvider = true;
break; break;
case "-enable-connection-pooling":
EnableConnectionPooling = true;
break;
case "-parent-pid": case "-parent-pid":
string nextArg = args[++i]; string nextArg = args[++i];
if (Int32.TryParse(nextArg, out int parsedInt)) if (Int32.TryParse(nextArg, out int parsedInt))
@@ -179,6 +182,11 @@ namespace Microsoft.SqlTools.Utility
/// </summary> /// </summary>
public bool EnableSqlAuthenticationProvider { get; private set; } = false; public bool EnableSqlAuthenticationProvider { get; private set; } = false;
/// <summary>
/// Enables connection pooling for all SQL connections, removing feature name identifier from application name to prevent unwanted connection pools.
/// </summary>
public bool EnableConnectionPooling { get; private set; } = false;
/// <summary> /// <summary>
/// The ID of the process that started this service. This is used to check when the parent /// 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. /// process exits so that the service process can exit at the same time.

View File

@@ -172,6 +172,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
/// </summary> /// </summary>
public bool EnableSqlAuthenticationProvider { get; set; } public bool EnableSqlAuthenticationProvider { get; set; }
/// <summary>
/// Enables connection pooling for all SQL connections, removing feature name identifier from application name to prevent unwanted connection pools.
/// </summary>
public static bool EnableConnectionPooling { get; set; }
/// <summary> /// <summary>
/// Returns a connection queue for given type /// Returns a connection queue for given type
/// </summary> /// </summary>
@@ -474,8 +479,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
internal static string GetApplicationNameWithFeature(string applicationName, string featureName) internal static string GetApplicationNameWithFeature(string applicationName, string featureName)
{ {
string appNameWithFeature = applicationName; string appNameWithFeature = applicationName;
// Connection Service will not set custom application name if connection pooling is enabled on service.
if (!string.IsNullOrWhiteSpace(applicationName) && !string.IsNullOrWhiteSpace(featureName) && !applicationName.EndsWith(featureName)) if (!EnableConnectionPooling && !string.IsNullOrWhiteSpace(applicationName) && !string.IsNullOrWhiteSpace(featureName) && !applicationName.EndsWith(featureName))
{ {
int azdataStartIndex = applicationName.IndexOf(Constants.DefaultApplicationName); int azdataStartIndex = applicationName.IndexOf(Constants.DefaultApplicationName);
string originalAppName = azdataStartIndex != -1 string originalAppName = azdataStartIndex != -1
@@ -671,7 +676,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
try try
{ {
connectionInfo.ConnectionDetails.Pooling = false; if (!EnableConnectionPooling)
{
connectionInfo.ConnectionDetails.Pooling = false;
}
// build the connection string from the input parameters // build the connection string from the input parameters
string connectionString = BuildConnectionString(connectionInfo.ConnectionDetails); string connectionString = BuildConnectionString(connectionInfo.ConnectionDetails);
@@ -1086,15 +1094,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
{ {
this.ServiceHost = serviceHost; 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. this.EnableSqlAuthenticationProvider = true;
var provider = new AuthenticationProvider(GetAuthenticator(commandOptions)); Logger.Information("Registering implementation of SQL Authentication provider for 'Active Directory Interactive' authentication mode.");
SqlAuthenticationProvider.SetProvider(SqlAuthenticationMethod.ActiveDirectoryInteractive, provider); }
if (commandOptions.EnableConnectionPooling)
this.EnableSqlAuthenticationProvider = true; {
Logger.Information("Registering implementation of SQL Authentication provider for 'Active Directory Interactive' authentication mode."); ConnectionService.EnableConnectionPooling = true;
Logger.Information("Connection pooling will be enabled for all SQL connections.");
}
} }
// Register request and event handlers with the Service Host // Register request and event handlers with the Service Host
@@ -1586,7 +1601,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
{ {
connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion; connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion;
} }
if (forceDisablePooling) if (!EnableConnectionPooling && forceDisablePooling)
{ {
connectionBuilder.Pooling = false; connectionBuilder.Pooling = false;
} }
@@ -1844,7 +1859,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
bool? originalPooling = connInfo.ConnectionDetails.Pooling; bool? originalPooling = connInfo.ConnectionDetails.Pooling;
// allow pooling connections for language service feature to improve intellisense connection retention and performance. // 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 // increase the connection and command timeout to at least 30 seconds and and build connection string
connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0); connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);