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:
Leila Lali
2017-08-21 14:32:48 -07:00
committed by GitHub
parent 39dedd88e0
commit 1511f73672
7 changed files with 108 additions and 71 deletions

View File

@@ -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

View File

@@ -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
}
}
} }
} }
} }
} }

View File

@@ -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

View File

@@ -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;

View File

@@ -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();
}
}
}
}
} }
} }

View File

@@ -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();
}
}
} }
} }

View File

@@ -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)
{ {