Enable connection pooling for languageService (#2080)

This commit is contained in:
Cheena Malhotra
2023-05-31 17:15:47 -07:00
committed by GitHub
parent 478b10d391
commit b45026967e
4 changed files with 28 additions and 14 deletions

View File

@@ -129,7 +129,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
if (connectionService == null) if (connectionService == null)
{ {
connectionService = ConnectionService.Instance; connectionService = ConnectionService.Instance;
connectionService.RegisterConnectedQueue("LanguageService", _bindingQueue); connectionService.RegisterConnectedQueue(Constants.LanguageServiceFeature, _bindingQueue);
} }
return connectionService; return connectionService;
} }
@@ -557,7 +557,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
{ {
try try
{ {
_bindingQueue.AddConnectionContext(connInfo, true, featureName: "LanguageService", overwrite: true); _bindingQueue.AddConnectionContext(connInfo, true, featureName: Constants.LanguageServiceFeature, overwrite: true);
RemoveScriptParseInfo(rebuildParams.OwnerUri); RemoveScriptParseInfo(rebuildParams.OwnerUri);
UpdateLanguageServiceOnConnection(connInfo).Wait(); UpdateLanguageServiceOnConnection(connInfo).Wait();
} }
@@ -677,7 +677,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
{ {
try try
{ {
scriptInfo.ConnectionKey = _bindingQueue.AddConnectionContext(connInfo, true,"languageService"); scriptInfo.ConnectionKey = _bindingQueue.AddConnectionContext(connInfo, true, Constants.LanguageServiceFeature);
scriptInfo.IsConnected = _bindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey); scriptInfo.IsConnected = _bindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey);
} }
catch (Exception ex) catch (Exception ex)

View File

@@ -16,6 +16,9 @@ namespace Microsoft.SqlTools.Hosting.Protocol
public static readonly string DefaultApplicationName = "azdata"; public static readonly string DefaultApplicationName = "azdata";
public static readonly string SqlLoginAuthenticationType = "SqlLogin"; public static readonly string SqlLoginAuthenticationType = "SqlLogin";
// Feature names
public static readonly string LanguageServiceFeature = "languageService";
static Constants() static Constants()
{ {
JsonSerializerSettings = new JsonSerializerSettings(); JsonSerializerSettings = new JsonSerializerSettings();

View File

@@ -1329,17 +1329,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
/// <summary> /// <summary>
/// Build a connection string from a connection details instance /// Build a connection string from a connection details instance
/// </summary> /// </summary>
/// <param name="connectionDetails"></param> /// <param name="connectionDetails">Connection details</param>
public static string BuildConnectionString(ConnectionDetails connectionDetails) /// <param name="forceDisablePooling">Whether to disable connection pooling, defaults to true.</param>
public static string BuildConnectionString(ConnectionDetails connectionDetails, bool forceDisablePooling = true)
{ {
return CreateConnectionStringBuilder(connectionDetails).ToString(); return CreateConnectionStringBuilder(connectionDetails, forceDisablePooling).ToString();
} }
/// <summary> /// <summary>
/// Build a connection string builder a connection details instance /// Build a connection string builder a connection details instance
/// </summary> /// </summary>
/// <param name="connectionDetails"></param> /// <param name="connectionDetails">Connection details</param>
public static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails) /// <param name="forceDisablePooling">Whether to disable connection pooling, defaults to true.</param>
public static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails, bool forceDisablePooling = true)
{ {
SqlConnectionStringBuilder connectionBuilder; SqlConnectionStringBuilder connectionBuilder;
@@ -1579,7 +1581,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
{ {
connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion; connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion;
} }
if (forceDisablePooling)
{
connectionBuilder.Pooling = false; connectionBuilder.Pooling = false;
}
return connectionBuilder; return connectionBuilder;
} }
@@ -1833,17 +1838,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo; bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo;
bool? originalPooling = connInfo.ConnectionDetails.Pooling; bool? originalPooling = connInfo.ConnectionDetails.Pooling;
// allow pooling connections for language service feature to improve intellisense connection retention and performance.
bool shouldForceDisablePooling = 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);
connInfo.ConnectionDetails.CommandTimeout = Math.Max(30, originalCommandTimeout ?? 0); connInfo.ConnectionDetails.CommandTimeout = Math.Max(30, originalCommandTimeout ?? 0);
// enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections // enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections
connInfo.ConnectionDetails.PersistSecurityInfo = true; connInfo.ConnectionDetails.PersistSecurityInfo = true;
// turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method // turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method
if (shouldForceDisablePooling) {
connInfo.ConnectionDetails.Pooling = false; connInfo.ConnectionDetails.Pooling = false;
}
connInfo.ConnectionDetails.ApplicationName = GetApplicationNameWithFeature(connInfo.ConnectionDetails.ApplicationName, featureName); connInfo.ConnectionDetails.ApplicationName = GetApplicationNameWithFeature(connInfo.ConnectionDetails.ApplicationName, featureName);
// generate connection string // generate connection string
string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails); string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails, shouldForceDisablePooling);
// restore original values // restore original values
connInfo.ConnectionDetails.ConnectTimeout = originalTimeout; connInfo.ConnectionDetails.ConnectTimeout = originalTimeout;

View File

@@ -172,7 +172,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
if (connectionService == null) if (connectionService == null)
{ {
connectionService = ConnectionService.Instance; connectionService = ConnectionService.Instance;
connectionService.RegisterConnectedQueue("LanguageService", bindingQueue); connectionService.RegisterConnectedQueue(Constants.LanguageServiceFeature, bindingQueue);
} }
return connectionService; return connectionService;
} }
@@ -720,7 +720,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
try try
{ {
this.BindingQueue.AddConnectionContext(connInfo, featureName: "LanguageService", overwrite: true); this.BindingQueue.AddConnectionContext(connInfo, featureName: Constants.LanguageServiceFeature, overwrite: true);
RemoveScriptParseInfo(rebuildParams.OwnerUri); RemoveScriptParseInfo(rebuildParams.OwnerUri);
UpdateLanguageServiceOnConnection(connInfo).Wait(); UpdateLanguageServiceOnConnection(connInfo).Wait();
} }
@@ -1004,7 +1004,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{ {
try try
{ {
scriptInfo.ConnectionKey = this.BindingQueue.AddConnectionContext(info, "languageService"); scriptInfo.ConnectionKey = this.BindingQueue.AddConnectionContext(info, Constants.LanguageServiceFeature);
scriptInfo.IsConnected = this.BindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey); scriptInfo.IsConnected = this.BindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey);
} }
catch (Exception ex) catch (Exception ex)