mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-17 02:51:45 -05:00
Add fix for SendEvent causing test to fail (#195)
Add flag in ServiceHost to ignore SendEvent errors
This commit is contained in:
@@ -9,6 +9,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Channel;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
|
||||||
|
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||||
|
|
||||||
namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
|
namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
|
||||||
{
|
{
|
||||||
@@ -28,6 +29,14 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
|
|||||||
private Dictionary<string, TaskCompletionSource<Message>> pendingRequests =
|
private Dictionary<string, TaskCompletionSource<Message>> pendingRequests =
|
||||||
new Dictionary<string, TaskCompletionSource<Message>>();
|
new Dictionary<string, TaskCompletionSource<Message>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// When true, SendEvent will ignore exceptions and write them
|
||||||
|
/// to the log instead. Intended to be used for test scenarios
|
||||||
|
/// where SendEvent throws exceptions unrelated to what is
|
||||||
|
/// being tested.
|
||||||
|
/// </summary>
|
||||||
|
internal static bool SendEventIgnoreExceptions = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the MessageDispatcher which allows registration of
|
/// Gets the MessageDispatcher which allows registration of
|
||||||
/// handlers for requests, responses, and events that are
|
/// handlers for requests, responses, and events that are
|
||||||
@@ -194,37 +203,52 @@ namespace Microsoft.SqlTools.ServiceLayer.Hosting.Protocol
|
|||||||
EventType<TParams> eventType,
|
EventType<TParams> eventType,
|
||||||
TParams eventParams)
|
TParams eventParams)
|
||||||
{
|
{
|
||||||
if (!this.protocolChannel.IsConnected)
|
try
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("SendEvent called when ProtocolChannel was not yet connected");
|
if (!this.protocolChannel.IsConnected)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("SendEvent called when ProtocolChannel was not yet connected");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some events could be raised from a different thread.
|
||||||
|
// To ensure that messages are written serially, dispatch
|
||||||
|
// dispatch the SendEvent call to the message loop thread.
|
||||||
|
|
||||||
|
if (!this.MessageDispatcher.InMessageLoopThread)
|
||||||
|
{
|
||||||
|
TaskCompletionSource<bool> writeTask = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
|
this.MessageDispatcher.SynchronizationContext.Post(
|
||||||
|
async (obj) =>
|
||||||
|
{
|
||||||
|
await this.protocolChannel.MessageWriter.WriteEvent(
|
||||||
|
eventType,
|
||||||
|
eventParams);
|
||||||
|
|
||||||
|
writeTask.SetResult(true);
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
return writeTask.Task;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this.protocolChannel.MessageWriter.WriteEvent(
|
||||||
|
eventType,
|
||||||
|
eventParams);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
// Some events could be raised from a different thread.
|
|
||||||
// To ensure that messages are written serially, dispatch
|
|
||||||
// dispatch the SendEvent call to the message loop thread.
|
|
||||||
|
|
||||||
if (!this.MessageDispatcher.InMessageLoopThread)
|
|
||||||
{
|
{
|
||||||
TaskCompletionSource<bool> writeTask = new TaskCompletionSource<bool>();
|
if (SendEventIgnoreExceptions)
|
||||||
|
{
|
||||||
this.MessageDispatcher.SynchronizationContext.Post(
|
Logger.Write(LogLevel.Verbose, "Exception in SendEvent " + ex.ToString());
|
||||||
async (obj) =>
|
}
|
||||||
{
|
else
|
||||||
await this.protocolChannel.MessageWriter.WriteEvent(
|
{
|
||||||
eventType,
|
throw;
|
||||||
eventParams);
|
}
|
||||||
|
|
||||||
writeTask.SetResult(true);
|
|
||||||
}, null);
|
|
||||||
|
|
||||||
return writeTask.Task;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return this.protocolChannel.MessageWriter.WriteEvent(
|
|
||||||
eventType,
|
|
||||||
eventParams);
|
|
||||||
}
|
}
|
||||||
|
return Task.FromResult(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
//
|
//
|
||||||
|
|
||||||
using Microsoft.SqlServer.Management.SqlParser.Parser;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.Connection;
|
using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Completion;
|
||||||
@@ -290,6 +289,7 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
|
|||||||
{
|
{
|
||||||
// When we make a connection to a live database
|
// When we make a connection to a live database
|
||||||
ScriptFile scriptFile;
|
ScriptFile scriptFile;
|
||||||
|
Hosting.ServiceHost.SendEventIgnoreExceptions = true;
|
||||||
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
|
ConnectionInfo connInfo = TestObjects.InitLiveConnectionInfo(out scriptFile);
|
||||||
|
|
||||||
// And we place the cursor after a function that should prompt for signature help
|
// And we place the cursor after a function that should prompt for signature help
|
||||||
@@ -308,12 +308,15 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServer
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// If we have a valid ScriptParseInfo and the SQL has already been parsed
|
// If the SQL has already been parsed
|
||||||
var service = LanguageService.Instance;
|
var service = LanguageService.Instance;
|
||||||
ScriptParseInfo parseInfo = service.GetScriptParseInfo(scriptFile.ClientFilePath);
|
|
||||||
await service.UpdateLanguageServiceOnConnection(connInfo);
|
await service.UpdateLanguageServiceOnConnection(connInfo);
|
||||||
|
|
||||||
// We should get back a non-null SignatureHelp
|
// We should get back a non-null ScriptParseInfo
|
||||||
|
ScriptParseInfo parseInfo = service.GetScriptParseInfo(scriptFile.ClientFilePath);
|
||||||
|
Assert.NotNull(parseInfo);
|
||||||
|
|
||||||
|
// And we should get back a non-null SignatureHelp
|
||||||
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, scriptFile);
|
SignatureHelp signatureHelp = service.GetSignatureHelp(textDocument, scriptFile);
|
||||||
Assert.NotNull(signatureHelp);
|
Assert.NotNull(signatureHelp);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user