From b45026967ed2c04b667402bb9d85bd6a2246c81c Mon Sep 17 00:00:00 2001
From: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Date: Wed, 31 May 2023 17:15:47 -0700
Subject: [PATCH] Enable connection pooling for languageService (#2080)
---
.../LanguageServices/LanguageService.cs | 6 ++---
.../Hosting/Protocol/Constants.cs | 3 +++
.../Connection/ConnectionService.cs | 27 +++++++++++++------
.../LanguageServices/LanguageService.cs | 6 ++---
4 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs b/src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs
index cf6876ac..d89def83 100644
--- a/src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs
+++ b/src/Microsoft.Kusto.ServiceLayer/LanguageServices/LanguageService.cs
@@ -129,7 +129,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
if (connectionService == null)
{
connectionService = ConnectionService.Instance;
- connectionService.RegisterConnectedQueue("LanguageService", _bindingQueue);
+ connectionService.RegisterConnectedQueue(Constants.LanguageServiceFeature, _bindingQueue);
}
return connectionService;
}
@@ -557,7 +557,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
{
try
{
- _bindingQueue.AddConnectionContext(connInfo, true, featureName: "LanguageService", overwrite: true);
+ _bindingQueue.AddConnectionContext(connInfo, true, featureName: Constants.LanguageServiceFeature, overwrite: true);
RemoveScriptParseInfo(rebuildParams.OwnerUri);
UpdateLanguageServiceOnConnection(connInfo).Wait();
}
@@ -677,7 +677,7 @@ namespace Microsoft.Kusto.ServiceLayer.LanguageServices
{
try
{
- scriptInfo.ConnectionKey = _bindingQueue.AddConnectionContext(connInfo, true,"languageService");
+ scriptInfo.ConnectionKey = _bindingQueue.AddConnectionContext(connInfo, true, Constants.LanguageServiceFeature);
scriptInfo.IsConnected = _bindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey);
}
catch (Exception ex)
diff --git a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/Constants.cs b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/Constants.cs
index ff899150..f2b7aabb 100644
--- a/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/Constants.cs
+++ b/src/Microsoft.SqlTools.Hosting/Hosting/Protocol/Constants.cs
@@ -16,6 +16,9 @@ namespace Microsoft.SqlTools.Hosting.Protocol
public static readonly string DefaultApplicationName = "azdata";
public static readonly string SqlLoginAuthenticationType = "SqlLogin";
+ // Feature names
+ public static readonly string LanguageServiceFeature = "languageService";
+
static Constants()
{
JsonSerializerSettings = new JsonSerializerSettings();
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
index 20bf15ec..d63a5709 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Connection/ConnectionService.cs
@@ -1329,17 +1329,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
///
/// Build a connection string from a connection details instance
///
- ///
- public static string BuildConnectionString(ConnectionDetails connectionDetails)
+ /// Connection details
+ /// Whether to disable connection pooling, defaults to true.
+ public static string BuildConnectionString(ConnectionDetails connectionDetails, bool forceDisablePooling = true)
{
- return CreateConnectionStringBuilder(connectionDetails).ToString();
+ return CreateConnectionStringBuilder(connectionDetails, forceDisablePooling).ToString();
}
///
/// Build a connection string builder a connection details instance
///
- ///
- public static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails)
+ /// Connection details
+ /// Whether to disable connection pooling, defaults to true.
+ public static SqlConnectionStringBuilder CreateConnectionStringBuilder(ConnectionDetails connectionDetails, bool forceDisablePooling = true)
{
SqlConnectionStringBuilder connectionBuilder;
@@ -1579,7 +1581,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
{
connectionBuilder.TypeSystemVersion = connectionDetails.TypeSystemVersion;
}
- connectionBuilder.Pooling = false;
+ if (forceDisablePooling)
+ {
+ connectionBuilder.Pooling = false;
+ }
return connectionBuilder;
}
@@ -1833,17 +1838,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Connection
bool? originalPersistSecurityInfo = connInfo.ConnectionDetails.PersistSecurityInfo;
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
connInfo.ConnectionDetails.ConnectTimeout = Math.Max(30, originalTimeout ?? 0);
connInfo.ConnectionDetails.CommandTimeout = Math.Max(30, originalCommandTimeout ?? 0);
// enable PersistSecurityInfo to handle issues in SMO where the connection context is lost in reconnections
connInfo.ConnectionDetails.PersistSecurityInfo = true;
+
// turn off connection pool to avoid hold locks on server resources after calling SqlConnection Close method
- connInfo.ConnectionDetails.Pooling = false;
+ if (shouldForceDisablePooling) {
+ connInfo.ConnectionDetails.Pooling = false;
+ }
connInfo.ConnectionDetails.ApplicationName = GetApplicationNameWithFeature(connInfo.ConnectionDetails.ApplicationName, featureName);
// generate connection string
- string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails);
+ string connectionString = ConnectionService.BuildConnectionString(connInfo.ConnectionDetails, shouldForceDisablePooling);
// restore original values
connInfo.ConnectionDetails.ConnectTimeout = originalTimeout;
diff --git a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
index b85f2680..08793b13 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/LanguageServices/LanguageService.cs
@@ -172,7 +172,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
if (connectionService == null)
{
connectionService = ConnectionService.Instance;
- connectionService.RegisterConnectedQueue("LanguageService", bindingQueue);
+ connectionService.RegisterConnectedQueue(Constants.LanguageServiceFeature, bindingQueue);
}
return connectionService;
}
@@ -720,7 +720,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
try
{
- this.BindingQueue.AddConnectionContext(connInfo, featureName: "LanguageService", overwrite: true);
+ this.BindingQueue.AddConnectionContext(connInfo, featureName: Constants.LanguageServiceFeature, overwrite: true);
RemoveScriptParseInfo(rebuildParams.OwnerUri);
UpdateLanguageServiceOnConnection(connInfo).Wait();
}
@@ -1004,7 +1004,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
try
{
- scriptInfo.ConnectionKey = this.BindingQueue.AddConnectionContext(info, "languageService");
+ scriptInfo.ConnectionKey = this.BindingQueue.AddConnectionContext(info, Constants.LanguageServiceFeature);
scriptInfo.IsConnected = this.BindingQueue.IsBindingContextConnected(scriptInfo.ConnectionKey);
}
catch (Exception ex)