mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
File Browser: Adding async task exception handling (#504)
* Replacing Dictionary with ConcurrentDictionary since values are accessed in async contexts * Adding new method to allow async tasks to be executed in the exception continuation * Adding unit tests for the aforementioned * Adding exception handling to async tasks in file browser service * Updating query execution async handling to use the async version * Removing unnecesary send result from continuewithonfaulted
This commit is contained in:
@@ -4,8 +4,7 @@
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Data.Common;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
@@ -14,6 +13,7 @@ using Microsoft.SqlTools.ServiceLayer.Connection;
|
||||
using Microsoft.SqlTools.ServiceLayer.Connection.ReliableConnection;
|
||||
using Microsoft.SqlTools.ServiceLayer.FileBrowser.Contracts;
|
||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||
using Microsoft.SqlTools.ServiceLayer.Utility;
|
||||
|
||||
namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
{
|
||||
@@ -26,9 +26,9 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
public static FileBrowserService Instance => LazyInstance.Value;
|
||||
|
||||
// Cache file browser operations for expanding node request
|
||||
private Dictionary<string, FileBrowserOperation> ownerToFileBrowserMap = new Dictionary<string, FileBrowserOperation>();
|
||||
private Dictionary<string, ValidatePathsCallback> validatePathsCallbackMap = new Dictionary<string, ValidatePathsCallback>();
|
||||
private ConnectionService connectionService = null;
|
||||
private readonly ConcurrentDictionary<string, FileBrowserOperation> ownerToFileBrowserMap = new ConcurrentDictionary<string, FileBrowserOperation>();
|
||||
private readonly ConcurrentDictionary<string, ValidatePathsCallback> validatePathsCallbackMap = new ConcurrentDictionary<string, ValidatePathsCallback>();
|
||||
private ConnectionService connectionService;
|
||||
|
||||
/// <summary>
|
||||
/// Signature for callback method that validates the selected file paths
|
||||
@@ -52,23 +52,6 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Service host object for sending/receiving requests/events.
|
||||
/// Internal for testing purposes.
|
||||
/// </summary>
|
||||
internal IProtocolEndpoint ServiceHost
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public FileBrowserService()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Register validate path callback
|
||||
/// </summary>
|
||||
@@ -76,23 +59,15 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
/// <param name="callback"></param>
|
||||
public void RegisterValidatePathsCallback(string service, ValidatePathsCallback callback)
|
||||
{
|
||||
if (this.validatePathsCallbackMap.ContainsKey(service))
|
||||
{
|
||||
this.validatePathsCallbackMap.Remove(service);
|
||||
}
|
||||
|
||||
this.validatePathsCallbackMap.Add(service, callback);
|
||||
validatePathsCallbackMap.AddOrUpdate(service, callback, (key, oldValue) => callback);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the service instance
|
||||
/// </summary>
|
||||
/// <param name="serviceHost"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="serviceHost">Service host to register handlers with</param>
|
||||
public void InitializeService(ServiceHost serviceHost)
|
||||
{
|
||||
this.ServiceHost = serviceHost;
|
||||
|
||||
// Open a file browser
|
||||
serviceHost.SetRequestHandler(FileBrowserOpenRequest.Type, HandleFileBrowserOpenRequest);
|
||||
|
||||
@@ -108,13 +83,12 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
|
||||
#region request handlers
|
||||
|
||||
internal async Task HandleFileBrowserOpenRequest(
|
||||
FileBrowserOpenParams fileBrowserParams,
|
||||
RequestContext<bool> requestContext)
|
||||
internal async Task HandleFileBrowserOpenRequest(FileBrowserOpenParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = Task.Run(() => RunFileBrowserOpenTask(fileBrowserParams));
|
||||
var task = Task.Run(() => RunFileBrowserOpenTask(fileBrowserParams, requestContext))
|
||||
.ContinueWithOnFaulted(null);
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
catch
|
||||
@@ -123,13 +97,12 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task HandleFileBrowserExpandRequest(
|
||||
FileBrowserExpandParams fileBrowserParams,
|
||||
RequestContext<bool> requestContext)
|
||||
internal async Task HandleFileBrowserExpandRequest(FileBrowserExpandParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = Task.Run(() => RunFileBrowserExpandTask(fileBrowserParams));
|
||||
var task = Task.Run(() => RunFileBrowserExpandTask(fileBrowserParams, requestContext))
|
||||
.ContinueWithOnFaulted(null);
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
catch
|
||||
@@ -138,13 +111,12 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
}
|
||||
}
|
||||
|
||||
internal async Task HandleFileBrowserValidateRequest(
|
||||
FileBrowserValidateParams fileBrowserParams,
|
||||
RequestContext<bool> requestContext)
|
||||
internal async Task HandleFileBrowserValidateRequest(FileBrowserValidateParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
var task = Task.Run(() => RunFileBrowserValidateTask(fileBrowserParams));
|
||||
var task = Task.Run(() => RunFileBrowserValidateTask(fileBrowserParams, requestContext))
|
||||
.ContinueWithOnFaulted(null);
|
||||
await requestContext.SendResult(true);
|
||||
}
|
||||
catch
|
||||
@@ -158,22 +130,15 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
RequestContext<FileBrowserCloseResponse> requestContext)
|
||||
{
|
||||
FileBrowserCloseResponse response = new FileBrowserCloseResponse();
|
||||
if (this.ownerToFileBrowserMap.ContainsKey(fileBrowserParams.OwnerUri))
|
||||
{
|
||||
this.ownerToFileBrowserMap.Remove(fileBrowserParams.OwnerUri);
|
||||
response.Succeeded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
response.Succeeded = false;
|
||||
}
|
||||
FileBrowserOperation removedOperation;
|
||||
response.Succeeded = ownerToFileBrowserMap.TryRemove(fileBrowserParams.OwnerUri, out removedOperation);
|
||||
|
||||
await requestContext.SendResult(response);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
internal async Task RunFileBrowserOpenTask(FileBrowserOpenParams fileBrowserParams)
|
||||
internal async Task RunFileBrowserOpenTask(FileBrowserOpenParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
FileBrowserOpenedParams result = new FileBrowserOpenedParams();
|
||||
|
||||
@@ -189,7 +154,7 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
connInfo.TryGetConnection(ConnectionType.Default, out dbConn);
|
||||
if (dbConn != null)
|
||||
{
|
||||
conn = ReliableConnectionHelper.GetAsSqlConnection((IDbConnection)dbConn);
|
||||
conn = ReliableConnectionHelper.GetAsSqlConnection(dbConn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,11 +163,7 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
FileBrowserOperation browser = new FileBrowserOperation(conn, fileBrowserParams.ExpandPath, fileBrowserParams.FileFilters);
|
||||
browser.PopulateFileTree();
|
||||
|
||||
if (this.ownerToFileBrowserMap.ContainsKey(fileBrowserParams.OwnerUri))
|
||||
{
|
||||
this.ownerToFileBrowserMap.Remove(fileBrowserParams.OwnerUri);
|
||||
}
|
||||
this.ownerToFileBrowserMap.Add(fileBrowserParams.OwnerUri, browser);
|
||||
ownerToFileBrowserMap.AddOrUpdate(fileBrowserParams.OwnerUri, browser, (key, value) => browser);
|
||||
|
||||
result.OwnerUri = fileBrowserParams.OwnerUri;
|
||||
result.FileTree = browser.FileTree;
|
||||
@@ -219,25 +180,21 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
result.Message = ex.Message;
|
||||
}
|
||||
|
||||
await ServiceHost.SendEvent(FileBrowserOpenedNotification.Type, result);
|
||||
await requestContext.SendEvent(FileBrowserOpenedNotification.Type, result);
|
||||
}
|
||||
|
||||
internal async Task RunFileBrowserExpandTask(FileBrowserExpandParams fileBrowserParams)
|
||||
internal async Task RunFileBrowserExpandTask(FileBrowserExpandParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
FileBrowserExpandedParams result = new FileBrowserExpandedParams();
|
||||
try
|
||||
{
|
||||
if (this.ownerToFileBrowserMap.ContainsKey(fileBrowserParams.OwnerUri))
|
||||
FileBrowserOperation browser;
|
||||
result.Succeeded = ownerToFileBrowserMap.TryGetValue(fileBrowserParams.OwnerUri, out browser);
|
||||
if (result.Succeeded && browser != null)
|
||||
{
|
||||
FileBrowserOperation browser = this.ownerToFileBrowserMap[fileBrowserParams.OwnerUri];
|
||||
result.Children = browser.GetChildren(fileBrowserParams.ExpandPath).ToArray();
|
||||
result.ExpandPath = fileBrowserParams.ExpandPath;
|
||||
result.OwnerUri = fileBrowserParams.OwnerUri;
|
||||
result.Succeeded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Succeeded = false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -246,22 +203,23 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
result.Message = ex.Message;
|
||||
}
|
||||
|
||||
await ServiceHost.SendEvent(FileBrowserExpandedNotification.Type, result);
|
||||
await requestContext.SendEvent(FileBrowserExpandedNotification.Type, result);
|
||||
}
|
||||
|
||||
internal async Task RunFileBrowserValidateTask(FileBrowserValidateParams fileBrowserParams)
|
||||
internal async Task RunFileBrowserValidateTask(FileBrowserValidateParams fileBrowserParams, RequestContext<bool> requestContext)
|
||||
{
|
||||
FileBrowserValidatedParams result = new FileBrowserValidatedParams();
|
||||
|
||||
try
|
||||
{
|
||||
if (this.validatePathsCallbackMap.ContainsKey(fileBrowserParams.ServiceType)
|
||||
&& this.validatePathsCallbackMap[fileBrowserParams.ServiceType] != null
|
||||
ValidatePathsCallback callback;
|
||||
if (validatePathsCallbackMap.TryGetValue(fileBrowserParams.ServiceType, out callback)
|
||||
&& callback != null
|
||||
&& fileBrowserParams.SelectedFiles != null
|
||||
&& fileBrowserParams.SelectedFiles.Length > 0)
|
||||
{
|
||||
string errorMessage;
|
||||
result.Succeeded = this.validatePathsCallbackMap[fileBrowserParams.ServiceType](new FileBrowserValidateEventArgs
|
||||
result.Succeeded = callback(new FileBrowserValidateEventArgs
|
||||
{
|
||||
ServiceType = fileBrowserParams.ServiceType,
|
||||
OwnerUri = fileBrowserParams.OwnerUri,
|
||||
@@ -284,7 +242,7 @@ namespace Microsoft.SqlTools.ServiceLayer.FileBrowser
|
||||
result.Message = ex.Message;
|
||||
}
|
||||
|
||||
await ServiceHost.SendEvent(FileBrowserValidatedNotification.Type, result);
|
||||
await requestContext.SendEvent(FileBrowserValidatedNotification.Type, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user