mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-02-16 10:58:30 -05:00
fixed the issue with resources not disposed correctly (#439)
* fixed the issue with resources not disposed correctly * disposing language service at shutdown
This commit is contained in:
@@ -1119,27 +1119,30 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
throw new ArgumentException("sourceXml");
|
throw new ArgumentException("sourceXml");
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryStream memoryStream = new MemoryStream();
|
using (MemoryStream memoryStream = new MemoryStream())
|
||||||
StreamWriter streamWriter = new StreamWriter(memoryStream);
|
{
|
||||||
|
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
|
||||||
|
{
|
||||||
|
// Writes the xml to the memory stream
|
||||||
|
streamWriter.Write(sourceXml);
|
||||||
|
streamWriter.Flush();
|
||||||
|
|
||||||
// Writes the xml to the memory stream
|
// Resets the stream to the beginning
|
||||||
streamWriter.Write(sourceXml);
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
||||||
streamWriter.Flush();
|
|
||||||
|
|
||||||
// Resets the stream to the beginning
|
// Creates the XML reader from the stream
|
||||||
memoryStream.Seek(0, SeekOrigin.Begin);
|
// and moves it to the correct node
|
||||||
|
XmlReader xmlReader = XmlReader.Create(memoryStream);
|
||||||
|
xmlReader.MoveToContent();
|
||||||
|
|
||||||
// Creates the XML reader from the stream
|
// generate the xml document
|
||||||
// and moves it to the correct node
|
XmlDocument xmlDocument = new XmlDocument();
|
||||||
XmlReader xmlReader = XmlReader.Create(memoryStream);
|
xmlDocument.PreserveWhitespace = true;
|
||||||
xmlReader.MoveToContent();
|
xmlDocument.LoadXml(xmlReader.ReadOuterXml());
|
||||||
|
|
||||||
// generate the xml document
|
return xmlDocument;
|
||||||
XmlDocument xmlDocument = new XmlDocument();
|
}
|
||||||
xmlDocument.PreserveWhitespace = true;
|
}
|
||||||
xmlDocument.LoadXml(xmlReader.ReadOuterXml());
|
|
||||||
|
|
||||||
return xmlDocument;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -647,17 +647,20 @@ WHERE do.database_id = @DbID
|
|||||||
{ //If it's under v12 we need to query the master DB directly since that has the views containing the necessary information
|
{ //If it's under v12 we need to query the master DB directly since that has the views containing the necessary information
|
||||||
using (var conn = new SqlConnection(context.Server.ConnectionContext.ConnectionString))
|
using (var conn = new SqlConnection(context.Server.ConnectionContext.ConnectionString))
|
||||||
{
|
{
|
||||||
var cmd = new SqlCommand(dbSloQuery, conn);
|
using (var cmd = new SqlCommand(dbSloQuery, conn))
|
||||||
cmd.Parameters.AddWithValue("@DbID", db.ID);
|
|
||||||
conn.Open();
|
|
||||||
SqlDataReader reader = cmd.ExecuteReader();
|
|
||||||
while (reader.Read())
|
|
||||||
{
|
{
|
||||||
this.configuredServiceLevelObjective = reader["configured_slo_name"].ToString();
|
cmd.Parameters.AddWithValue("@DbID", db.ID);
|
||||||
this.currentServiceLevelObjective = reader["current_slo_name"].ToString();
|
conn.Open();
|
||||||
break; //Got our service level objective so we're done
|
using (SqlDataReader reader = cmd.ExecuteReader())
|
||||||
|
{
|
||||||
|
while (reader.Read())
|
||||||
|
{
|
||||||
|
this.configuredServiceLevelObjective = reader["configured_slo_name"].ToString();
|
||||||
|
this.currentServiceLevelObjective = reader["current_slo_name"].ToString();
|
||||||
|
break; //Got our service level objective so we're done
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -177,33 +177,35 @@ namespace Microsoft.SqlTools.ServiceLayer.Admin
|
|||||||
|
|
||||||
//Altering the DB needs to be done on the master DB
|
//Altering the DB needs to be done on the master DB
|
||||||
using (var conn = new SqlConnection(this.context.ServerConnection.GetDatabaseConnection("master").ConnectionString))
|
using (var conn = new SqlConnection(this.context.ServerConnection.GetDatabaseConnection("master").ConnectionString))
|
||||||
{
|
{
|
||||||
var cmd = new SqlCommand();
|
using (var cmd = new SqlCommand())
|
||||||
cmd.Connection = conn;
|
{
|
||||||
conn.Open();
|
cmd.Connection = conn;
|
||||||
|
conn.Open();
|
||||||
|
|
||||||
//Only run the alter statements for modifications made. This is mostly to allow the non-Azure specific
|
//Only run the alter statements for modifications made. This is mostly to allow the non-Azure specific
|
||||||
//properties to be updated when a SLO change is in progress, but it also is beneficial to save trips to the
|
//properties to be updated when a SLO change is in progress, but it also is beneficial to save trips to the
|
||||||
//server whenever we can (especially when Azure is concerned)
|
//server whenever we can (especially when Azure is concerned)
|
||||||
if (currentState.azureEdition != originalState.azureEdition ||
|
if (currentState.azureEdition != originalState.azureEdition ||
|
||||||
currentState.currentServiceLevelObjective != originalState.currentServiceLevelObjective ||
|
currentState.currentServiceLevelObjective != originalState.currentServiceLevelObjective ||
|
||||||
currentState.maxSize != originalState.maxSize)
|
currentState.maxSize != originalState.maxSize)
|
||||||
{
|
{
|
||||||
cmd.CommandText = alterDbPropertiesStatement;
|
cmd.CommandText = alterDbPropertiesStatement;
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentState.recursiveTriggers != originalState.recursiveTriggers)
|
if (currentState.recursiveTriggers != originalState.recursiveTriggers)
|
||||||
{
|
{
|
||||||
cmd.CommandText = alterAzureDbRecursiveTriggersEnabledStatement;
|
cmd.CommandText = alterAzureDbRecursiveTriggersEnabledStatement;
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentState.isReadOnly != originalState.isReadOnly)
|
if (currentState.isReadOnly != originalState.isReadOnly)
|
||||||
{
|
{
|
||||||
cmd.CommandText = alterAzureDbIsReadOnlyStatement;
|
cmd.CommandText = alterAzureDbIsReadOnlyStatement;
|
||||||
cmd.ExecuteNonQuery();
|
cmd.ExecuteNonQuery();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Because we didn't use SMO to do the alter we should refresh the DB object so it picks up the correct properties
|
//Because we didn't use SMO to do the alter we should refresh the DB object so it picks up the correct properties
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Copyright (c) Microsoft. All rights reserved.
|
// Copyright (c) Microsoft. All rights reserved.
|
||||||
// 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 System;
|
||||||
using Microsoft.SqlTools.Credentials;
|
using Microsoft.SqlTools.Credentials;
|
||||||
using Microsoft.SqlTools.Extensibility;
|
using Microsoft.SqlTools.Extensibility;
|
||||||
using Microsoft.SqlTools.Hosting;
|
using Microsoft.SqlTools.Hosting;
|
||||||
@@ -13,7 +14,6 @@ using Microsoft.SqlTools.ServiceLayer.EditData;
|
|||||||
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
using Microsoft.SqlTools.ServiceLayer.Hosting;
|
||||||
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
using Microsoft.SqlTools.ServiceLayer.LanguageServices;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Metadata;
|
using Microsoft.SqlTools.ServiceLayer.Metadata;
|
||||||
using Microsoft.SqlTools.ServiceLayer.ObjectExplorer;
|
|
||||||
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
using Microsoft.SqlTools.ServiceLayer.QueryExecution;
|
||||||
using Microsoft.SqlTools.ServiceLayer.Scripting;
|
using Microsoft.SqlTools.ServiceLayer.Scripting;
|
||||||
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
using Microsoft.SqlTools.ServiceLayer.SqlContext;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main class for the Binding Queue
|
/// Main class for the Binding Queue
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BindingQueue<T> where T : IBindingContext, new()
|
public class BindingQueue<T> : IDisposable where T : IBindingContext, new()
|
||||||
{
|
{
|
||||||
private CancellationTokenSource processQueueCancelToken = new CancellationTokenSource();
|
private CancellationTokenSource processQueueCancelToken = new CancellationTokenSource();
|
||||||
|
|
||||||
@@ -313,5 +313,24 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (itemQueuedEvent != null)
|
||||||
|
{
|
||||||
|
itemQueuedEvent.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.BindingContextMap != null)
|
||||||
|
{
|
||||||
|
foreach (var item in this.BindingContextMap)
|
||||||
|
{
|
||||||
|
if (item.Value != null && item.Value.ServerConnection != null && item.Value.ServerConnection.SqlConnectionObject != null)
|
||||||
|
{
|
||||||
|
item.Value.ServerConnection.SqlConnectionObject.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
/// Main class for Language Service functionality including anything that requires knowledge of
|
/// Main class for Language Service functionality including anything that requires knowledge of
|
||||||
/// the language to perform, such as definitions, intellisense, etc.
|
/// the language to perform, such as definitions, intellisense, etc.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class LanguageService
|
public sealed class LanguageService: IDisposable
|
||||||
{
|
{
|
||||||
#region Singleton Instance Implementation
|
#region Singleton Instance Implementation
|
||||||
|
|
||||||
@@ -249,6 +249,7 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
{
|
{
|
||||||
Logger.Write(LogLevel.Verbose, "Shutting down language service");
|
Logger.Write(LogLevel.Verbose, "Shutting down language service");
|
||||||
DeletePeekDefinitionScripts();
|
DeletePeekDefinitionScripts();
|
||||||
|
this.Dispose();
|
||||||
await Task.FromResult(0);
|
await Task.FromResult(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1716,5 +1717,13 @@ namespace Microsoft.SqlTools.ServiceLayer.LanguageServices
|
|||||||
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (bindingQueue != null)
|
||||||
|
{
|
||||||
|
bindingQueue.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,28 +148,29 @@ namespace Microsoft.SqlTools.ServiceLayer.TaskServices
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (TaskToCancel != null)
|
using (AutoResetEvent onCompletedEvent = new AutoResetEvent(initialState: false))
|
||||||
{
|
{
|
||||||
AutoResetEvent onCompletedEvent = new AutoResetEvent(initialState: false);
|
if (TaskToCancel != null)
|
||||||
Task<TaskResult> cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, onCompletedEvent));
|
|
||||||
|
|
||||||
completedTask = await Task.WhenAny(performTask, cancelTask);
|
|
||||||
|
|
||||||
// Release the cancelTask
|
|
||||||
if (completedTask == performTask)
|
|
||||||
{
|
{
|
||||||
onCompletedEvent.Set();
|
Task<TaskResult> cancelTask = Task.Run(() => CancelTaskAsync(TokenSource.Token, onCompletedEvent));
|
||||||
|
|
||||||
|
completedTask = await Task.WhenAny(performTask, cancelTask);
|
||||||
|
|
||||||
|
// Release the cancelTask
|
||||||
|
if (completedTask == performTask)
|
||||||
|
{
|
||||||
|
onCompletedEvent.Set();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
completedTask = await Task.WhenAny(performTask);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
completedTask = await Task.WhenAny(performTask);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.TaskCompleted,
|
|
||||||
completedTask.Result.TaskStatus);
|
|
||||||
taskResult = completedTask.Result;
|
|
||||||
|
|
||||||
|
AddMessage(completedTask.Result.TaskStatus == SqlTaskStatus.Failed ? completedTask.Result.ErrorMessage : SR.TaskCompleted,
|
||||||
|
completedTask.Result.TaskStatus);
|
||||||
|
taskResult = completedTask.Result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user