Skip to content

Commit

Permalink
preload database when database node is expanded (#1690)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanrenmsft authored Sep 15, 2022
1 parent 8bdf1d8 commit 6e007e6
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Tools.Sql.DesignServices.TableDesigner;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlTools.Extensibility;
using Microsoft.SqlTools.Hosting;
Expand All @@ -23,6 +24,7 @@
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.Nodes;
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer.SmoModel;
using Microsoft.SqlTools.ServiceLayer.SqlContext;
using Microsoft.SqlTools.ServiceLayer.TableDesigner;
using Microsoft.SqlTools.ServiceLayer.Utility;
using Microsoft.SqlTools.ServiceLayer.Workspace;
using Microsoft.SqlTools.Utility;
Expand Down Expand Up @@ -381,6 +383,27 @@ internal ExpandResponse QueueExpandNodeRequest(ObjectExplorerSession session, st
TreeNode node = session.Root.FindNodeByPath(nodePath);
ExpandResponse response = null;

// Performance Optimization for table designer to load the database model earlier based on user configuration.
if (node.NodeTypeId == NodeTypes.Database && TableDesignerService.Instance.Settings.PreloadDatabaseModel)
{
// The operation below are not blocking, but just in case, wrapping it with a task run to make sure it has no impact on the node expansion time.
var _ = Task.Run(() =>
{
try
{
var builder = ConnectionService.CreateConnectionStringBuilder(session.ConnectionInfo.ConnectionDetails);
builder.InitialCatalog = node.NodeValue;
builder.ApplicationName = TableDesignerService.TableDesignerApplicationName;
var azureToken = session.ConnectionInfo.ConnectionDetails.AzureAccountToken;
TableDesignerCacheManager.StartDatabaseModelInitialization(builder.ToString(), azureToken);
}
catch (Exception ex)
{
Logger.Write(TraceEventType.Warning, $"Failed to start database initialization for table designer: {ex.Message}");
}
});
}

// This node was likely returned from a different node provider. Ignore expansion and return an empty array
// since we don't need to add any nodes under this section of the tree.
if (node == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public SqlToolsSettingsValues(bool createDefaults = true)
IntelliSense = new IntelliSenseSettings();
QueryExecutionSettings = new QueryExecutionSettings();
Format = new FormatterSettings();
TableDesigner = new TableDesignerSettings();
}
}

Expand All @@ -48,5 +49,11 @@ public SqlToolsSettingsValues(bool createDefaults = true)
/// </summary>
[JsonProperty("objectExplorer")]
public ObjectExplorerSettings ObjectExplorer { get; set; }

/// <summary>
/// Gets or sets the table designer settings
/// </summary>
[JsonProperty("tableDesigner")]
public TableDesignerSettings TableDesigner { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//

namespace Microsoft.SqlTools.ServiceLayer.SqlContext
{
/// <summary>
/// Contract for receiving table designer settings as part of workspace settings
/// </summary>
public class TableDesignerSettings
{
/// <summary>
/// Whether the database model should be preloaded to make the initial launch quicker.
/// </summary>
public bool PreloadDatabaseModel { get; set; } = false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.SqlTools.ServiceLayer.TableDesigner.Contracts;
using Dac = Microsoft.Data.Tools.Sql.DesignServices.TableDesigner;
using STSHost = Microsoft.SqlTools.ServiceLayer.Hosting.ServiceHost;
using Microsoft.SqlTools.ServiceLayer.SqlContext;

namespace Microsoft.SqlTools.ServiceLayer.TableDesigner
{
Expand All @@ -32,6 +33,8 @@ public TableDesignerService()
{
}

public TableDesignerSettings Settings { get; private set; } = new TableDesignerSettings();

/// <summary>
/// Gets the singleton instance object
/// </summary>
Expand Down Expand Up @@ -61,7 +64,16 @@ public void InitializeService(ServiceHost serviceHost)
this.ServiceHost.SetRequestHandler(GenerateScriptRequest.Type, HandleGenerateScriptRequest);
this.ServiceHost.SetRequestHandler(GeneratePreviewReportRequest.Type, HandleGeneratePreviewReportRequest);
this.ServiceHost.SetRequestHandler(DisposeTableDesignerRequest.Type, HandleDisposeTableDesignerRequest);
Workspace.WorkspaceService<SqlToolsSettings>.Instance.RegisterConfigChangeCallback(UpdateSettings);

}

internal Task UpdateSettings(SqlToolsSettings newSettings, SqlToolsSettings oldSettings, EventContext eventContext)
{
Settings.PreloadDatabaseModel = newSettings.MssqlTools.TableDesigner.PreloadDatabaseModel;
return Task.FromResult(0);
}

private Task HandleRequest<T>(RequestContext<T> requestContext, Func<Task> action)
{
// The request handling will take some time to return, we need to use a separate task to run the request handler so that it won't block the main thread.
Expand Down

0 comments on commit 6e007e6

Please sign in to comment.