Sending status change notifications from server (#186)

* Sending status change notifications from server
This commit is contained in:
Leila Lali
2016-12-14 13:19:02 -08:00
committed by GitHub
parent 8cb35d00a6
commit e9398f7182
5 changed files with 119 additions and 19 deletions

View File

@@ -0,0 +1,35 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts
{
/// <summary>
/// Parameters sent back with an status change event
/// </summary>
public class StatusChangeParams
{
/// <summary>
/// URI identifying the text document
/// </summary>
public string OwnerUri { get; set; }
/// <summary>
/// The new status for the document
/// </summary>
public string Status { get; set; }
}
/// <summary>
/// Event sent for language service status change notification
/// </summary>
public class StatusChangedNotification
{
public static readonly
EventType<StatusChangeParams> Type =
EventType<StatusChangeParams>.Create("textDocument/statusChanged");
}
}

View File

@@ -0,0 +1,58 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Threading.Tasks;
using Microsoft.SqlTools.ServiceLayer.Hosting;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
{
/// <summary>
/// Helper class to send events to the client
/// </summary>
public class DocumentStatusHelper
{
public const string DefinitionRequested = "DefinitionRequested";
public const string DefinitionRequestCompleted = "DefinitionRequestCompleted";
/// <summary>
/// Sends an event for specific document using the existing request context
/// </summary>
public static void SendStatusChange<T>(RequestContext<T> requestContext, TextDocumentPosition textDocumentPosition, string status)
{
Task.Factory.StartNew(async () =>
{
if (requestContext != null)
{
string ownerUri = textDocumentPosition != null && textDocumentPosition.TextDocument != null ? textDocumentPosition.TextDocument.Uri : "";
await requestContext.SendEvent(StatusChangedNotification.Type, new StatusChangeParams()
{
OwnerUri = ownerUri,
Status = status
});
}
});
}
/// <summary>
/// Sends a telemetry event for specific document using the existing request context
/// </summary>
public static void SendTelemetryEvent<T>(RequestContext<T> requestContext, string telemetryEvent)
{
Task.Factory.StartNew(async () =>
{
await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
{
Params = new TelemetryProperties
{
EventName = telemetryEvent
}
});
});
}
}
}

View File

@@ -300,6 +300,17 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
internal static async Task HandleDefinitionRequest(TextDocumentPosition textDocumentPosition, RequestContext<Location[]> requestContext)
{
// Send a notification to signal that definition is sent
await requestContext.SendEvent(TelemetryNotification.Type, new TelemetryParams()
{
Params = new TelemetryProperties
{
EventName = TelemetryEventNames.PeekDefinitionRequested
}
});
DocumentStatusHelper.SendTelemetryEvent(requestContext, TelemetryEventNames.PeekDefinitionRequested);
DocumentStatusHelper.SendStatusChange(requestContext, textDocumentPosition, DocumentStatusHelper.DefinitionRequested);
if (WorkspaceService<SqlToolsSettings>.Instance.CurrentSettings.IsIntelliSenseEnabled)
{
// Retrieve document and connection
@@ -311,17 +322,9 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
if (locations != null)
{
await requestContext.SendResult(locations);
// Send a notification to signal that definition is sent
await ServiceHost.Instance.SendEvent(TelemetryNotification.Type, new TelemetryParams()
{
Params = new TelemetryProperties
{
EventName = TelemetryEventNames.PeekDefinitionRequested
}
});
}
}
DocumentStatusHelper.SendStatusChange(requestContext, textDocumentPosition, DocumentStatusHelper.DefinitionRequestCompleted);
}
// turn off this code until needed (10/28/2016)

View File

@@ -122,7 +122,7 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests
TestServerType serverType = TestServerType.OnPrem;
using (TestHelper testHelper = new TestHelper())
{
await VerifyBindingLoadScenario(testHelper, TestServerType.OnPrem, Scripts.TestDbSimpleSelectQuery, false);
await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbSimpleSelectQuery, false);
}
}
@@ -170,10 +170,10 @@ namespace Microsoft.SqlTools.ServiceLayer.PerfTests
[CreateTestDb(TestServerType.Azure)]
public async Task BindingCacheColdOnPremComplexQuery()
{
TestServerType serverType = TestServerType.Azure;
TestServerType serverType = TestServerType.OnPrem;
using (TestHelper testHelper = new TestHelper())
{
await VerifyBindingLoadScenario(testHelper, TestServerType.OnPrem, Scripts.TestDbComplexSelectQueries, false);
await VerifyBindingLoadScenario(testHelper, serverType, Scripts.TestDbComplexSelectQueries, false);
}
}

View File

@@ -3,24 +3,26 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.SqlServer.Management.SqlParser.Binder;
using Microsoft.SqlServer.Management.SqlParser.MetadataProvider;
using Microsoft.SqlServer.Management.SqlParser.Parser;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol;
using Microsoft.SqlTools.ServiceLayer.Hosting.Protocol.Contracts;
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
using Microsoft.SqlTools.ServiceLayer.LanguageServices.Contracts;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.Test.QueryExecution;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.ServiceLayer.Workspace.Contracts;
using Microsoft.SqlTools.Test.Utility;
using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
using Moq;
using Xunit;
using Location = Microsoft.SqlTools.ServiceLayer.Workspace.Contracts.Location;
namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
{
@@ -89,6 +91,8 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
requestContext = new Mock<RequestContext<Location[]>>();
requestContext.Setup(rc => rc.SendResult(It.IsAny<Location[]>()))
.Returns(Task.FromResult(0));
requestContext.Setup(r => r.SendEvent(It.IsAny<EventType<TelemetryParams>>(), It.IsAny<TelemetryParams>()));
requestContext.Setup(r => r.SendEvent(It.IsAny<EventType<StatusChangeParams>>(), It.IsAny<StatusChangeParams>()));
// setup the IBinder mock
binder = new Mock<IBinder>();
@@ -114,13 +118,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.LanguageServices
/// Tests the definition event handler. When called with no active connection, no definition is sent
/// </summary>
[Fact]
public void DefinitionsHandlerWithNoConnectionTest()
public async Task DefinitionsHandlerWithNoConnectionTest()
{
TestObjects.InitializeTestServices();
InitializeTestObjects();
// request the completion list
Task handleCompletion = LanguageService.HandleDefinitionRequest(textDocument, requestContext.Object);
handleCompletion.Wait(TaskTimeout);
await Task.WhenAny(LanguageService.HandleDefinitionRequest(textDocument, requestContext.Object), Task.Delay(TaskTimeout));
// verify that send result was not called
requestContext.Verify(m => m.SendResult(It.IsAny<Location[]>()), Times.Never());
}