mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
Switch back to event from locks to fix blocking issues. (#111)
This commit is contained in:
@@ -198,13 +198,17 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
int bindTimeout = queueItem.BindingTimeout ?? bindingContext.BindingTimeout;
|
int bindTimeout = queueItem.BindingTimeout ?? bindingContext.BindingTimeout;
|
||||||
|
|
||||||
// handle the case a previous binding operation is still running
|
// handle the case a previous binding operation is still running
|
||||||
if (!Monitor.TryEnter(bindingContext.BindingLock, bindTimeout))
|
if (!bindingContext.BindingLock.WaitOne(0))
|
||||||
{
|
{
|
||||||
queueItem.Result = queueItem.TimeoutOperation(bindingContext);
|
queueItem.Result = queueItem.TimeoutOperation != null
|
||||||
queueItem.ItemProcessed.Set();
|
? queueItem.TimeoutOperation(bindingContext)
|
||||||
|
: null;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindingContext.BindingLock.Reset();
|
||||||
|
|
||||||
lockTaken = true;
|
lockTaken = true;
|
||||||
|
|
||||||
// execute the binding operation
|
// execute the binding operation
|
||||||
@@ -232,8 +236,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
queueItem.Result = queueItem.TimeoutOperation(bindingContext);
|
queueItem.Result = queueItem.TimeoutOperation(bindingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we'll need to wait for the task to finsh canceling otherwise future binding will fail
|
lockTaken = false;
|
||||||
bindTask.Wait();
|
|
||||||
|
bindTask.ContinueWith((a) => bindingContext.BindingLock.Set());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -246,7 +251,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
if (lockTaken)
|
if (lockTaken)
|
||||||
{
|
{
|
||||||
Monitor.Exit(bindingContext.BindingLock);
|
bindingContext.BindingLock.Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
queueItem.ItemProcessed.Set();
|
queueItem.ItemProcessed.Set();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading;
|
||||||
using Microsoft.SqlServer.Management.Common;
|
using Microsoft.SqlServer.Management.Common;
|
||||||
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
using Microsoft.SqlServer.Management.SmoMetadataProvider;
|
||||||
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
using Microsoft.SqlServer.Management.SqlParser.Binder;
|
||||||
@@ -20,7 +21,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
private ParseOptions parseOptions;
|
private ParseOptions parseOptions;
|
||||||
|
|
||||||
private object bindingLock;
|
private ManualResetEvent bindingLock;
|
||||||
|
|
||||||
private ServerConnection serverConnection;
|
private ServerConnection serverConnection;
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ConnectedBindingContext()
|
public ConnectedBindingContext()
|
||||||
{
|
{
|
||||||
this.bindingLock = new object();
|
this.bindingLock = new ManualResetEvent(initialState: true);
|
||||||
this.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
this.BindingTimeout = ConnectedBindingQueue.DefaultBindingTimeout;
|
||||||
this.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
this.MetadataDisplayInfoProvider = new MetadataDisplayInfoProvider();
|
||||||
}
|
}
|
||||||
@@ -75,7 +76,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the binding lock object
|
/// Gets the binding lock object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object BindingLock
|
public ManualResetEvent BindingLock
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConnectedBindingQueue : BindingQueue<ConnectedBindingContext>
|
public class ConnectedBindingQueue : BindingQueue<ConnectedBindingContext>
|
||||||
{
|
{
|
||||||
internal const int DefaultBindingTimeout = 60000;
|
internal const int DefaultBindingTimeout = 500;
|
||||||
|
|
||||||
internal const int DefaultMinimumConnectionTimeout = 30;
|
internal const int DefaultMinimumConnectionTimeout = 30;
|
||||||
|
|
||||||
@@ -63,10 +63,12 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
string connectionKey = GetConnectionContextKey(connInfo);
|
string connectionKey = GetConnectionContextKey(connInfo);
|
||||||
IBindingContext bindingContext = this.GetOrCreateBindingContext(connectionKey);
|
IBindingContext bindingContext = this.GetOrCreateBindingContext(connectionKey);
|
||||||
|
|
||||||
lock (bindingContext.BindingLock)
|
if (bindingContext.BindingLock.WaitOne())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
bindingContext.BindingLock.Reset();
|
||||||
|
|
||||||
// increase the connection timeout to at least 30 seconds and and build connection string
|
// increase the connection timeout to at least 30 seconds and and build connection string
|
||||||
// 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
|
||||||
int? originalTimeout = connInfo.ConnectionDetails.ConnectTimeout;
|
int? originalTimeout = connInfo.ConnectionDetails.ConnectTimeout;
|
||||||
@@ -97,6 +99,10 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
bindingContext.IsConnected = false;
|
bindingContext.IsConnected = false;
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
bindingContext.BindingLock.Set();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return connectionKey;
|
return connectionKey;
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the binding lock object
|
/// Gets the binding lock object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
object BindingLock { get; }
|
ManualResetEvent BindingLock { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the binding operation timeout in milliseconds
|
/// Gets or sets the binding operation timeout in milliseconds
|
||||||
|
|||||||
@@ -37,11 +37,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
|
|
||||||
internal const int DiagnosticParseDelay = 750;
|
internal const int DiagnosticParseDelay = 750;
|
||||||
|
|
||||||
internal const int HoverTimeout = 3000;
|
internal const int HoverTimeout = 500;
|
||||||
|
|
||||||
internal const int BindingTimeout = 3000;
|
internal const int BindingTimeout = 500;
|
||||||
|
|
||||||
internal const int FindCompletionStartTimeout = 50;
|
|
||||||
|
|
||||||
internal const int OnConnectionWaitTimeout = 300000;
|
internal const int OnConnectionWaitTimeout = 300000;
|
||||||
|
|
||||||
@@ -628,7 +626,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
ScriptParseInfo scriptParseInfo = GetScriptParseInfo(textDocumentPosition.TextDocument.Uri);
|
ScriptParseInfo scriptParseInfo = GetScriptParseInfo(textDocumentPosition.TextDocument.Uri);
|
||||||
if (scriptParseInfo != null && scriptParseInfo.ParseResult != null)
|
if (scriptParseInfo != null && scriptParseInfo.ParseResult != null)
|
||||||
{
|
{
|
||||||
if (Monitor.TryEnter(scriptParseInfo.BuildingMetadataLock, LanguageService.FindCompletionStartTimeout))
|
if (Monitor.TryEnter(scriptParseInfo.BuildingMetadataLock))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -711,8 +709,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
Token token = GetToken(scriptParseInfo, line, column);
|
Token token = GetToken(scriptParseInfo, line, column);
|
||||||
|
|
||||||
if (scriptParseInfo.IsConnected
|
if (scriptParseInfo.IsConnected && Monitor.TryEnter(scriptParseInfo.BuildingMetadataLock))
|
||||||
&& Monitor.TryEnter(scriptParseInfo.BuildingMetadataLock, LanguageService.FindCompletionStartTimeout))
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
{
|
{
|
||||||
public TestBindingContext()
|
public TestBindingContext()
|
||||||
{
|
{
|
||||||
this.BindingLock = new object();
|
this.BindingLock = new ManualResetEvent(true);
|
||||||
this.BindingTimeout = 3000;
|
this.BindingTimeout = 3000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
|
|||||||
|
|
||||||
public IBinder Binder { get; set; }
|
public IBinder Binder { get; set; }
|
||||||
|
|
||||||
public object BindingLock { get; set; }
|
public ManualResetEvent BindingLock { get; set; }
|
||||||
|
|
||||||
public int BindingTimeout { get; set; }
|
public int BindingTimeout { get; set; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user