diff --git a/src/Microsoft.SqlTools.ServiceLayer/Profiler/ProfilerService.cs b/src/Microsoft.SqlTools.ServiceLayer/Profiler/ProfilerService.cs index 3a46ab2f..ff28965d 100644 --- a/src/Microsoft.SqlTools.ServiceLayer/Profiler/ProfilerService.cs +++ b/src/Microsoft.SqlTools.ServiceLayer/Profiler/ProfilerService.cs @@ -124,41 +124,44 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal async Task HandleCreateXEventSessionRequest(CreateXEventSessionParams parameters, RequestContext requestContext) { - try + await Task.Run(async () => { - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection( - parameters.OwnerUri, - out connInfo); - if (connInfo == null) + try { - throw new Exception(SR.ProfilerConnectionNotFound); - } - else if (parameters.SessionName == null) - { - throw new ArgumentNullException("SessionName"); - } - else if (parameters.Template == null) - { - throw new ArgumentNullException("Template"); - } - else - { - // create a new XEvent session and Profiler session - var xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo); - // start monitoring the profiler session - monitor.StartMonitoringSession(parameters.OwnerUri, xeSession); + ConnectionInfo connInfo; + ConnectionServiceInstance.TryFindConnection( + parameters.OwnerUri, + out connInfo); + if (connInfo == null) + { + throw new Exception(SR.ProfilerConnectionNotFound); + } + else if (parameters.SessionName == null) + { + throw new ArgumentNullException("SessionName"); + } + else if (parameters.Template == null) + { + throw new ArgumentNullException("Template"); + } + else + { + // create a new XEvent session and Profiler session + var xeSession = this.XEventSessionFactory.CreateXEventSession(parameters.Template.CreateStatement, parameters.SessionName, connInfo); + // start monitoring the profiler session + monitor.StartMonitoringSession(parameters.OwnerUri, xeSession); - var result = new CreateXEventSessionResult(); - await requestContext.SendResult(result); - - SessionCreatedNotification(parameters.OwnerUri, parameters.SessionName, parameters.Template.Name); + var result = new CreateXEventSessionResult(); + await requestContext.SendResult(result); + + SessionCreatedNotification(parameters.OwnerUri, parameters.SessionName, parameters.Template.Name); + } } - } - catch (Exception e) - { - await requestContext.SendError(new Exception(SR.CreateSessionFailed(e.Message))); - } + catch (Exception e) + { + await requestContext.SendError(new Exception(SR.CreateSessionFailed(e.Message))); + } + }); } /// @@ -166,31 +169,34 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal async Task HandleStartProfilingRequest(StartProfilingParams parameters, RequestContext requestContext) { - try + await Task.Run(async () => { - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection( - parameters.OwnerUri, - out connInfo); - if (connInfo != null) + try { - // create a new XEvent session and Profiler session - var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo); - // start monitoring the profiler session - monitor.StartMonitoringSession(parameters.OwnerUri, xeSession); + ConnectionInfo connInfo; + ConnectionServiceInstance.TryFindConnection( + parameters.OwnerUri, + out connInfo); + if (connInfo != null) + { + // create a new XEvent session and Profiler session + var xeSession = this.XEventSessionFactory.GetXEventSession(parameters.SessionName, connInfo); + // start monitoring the profiler session + monitor.StartMonitoringSession(parameters.OwnerUri, xeSession); - var result = new StartProfilingResult(); - await requestContext.SendResult(result); + var result = new StartProfilingResult(); + await requestContext.SendResult(result); + } + else + { + throw new Exception(SR.ProfilerConnectionNotFound); + } } - else + catch (Exception e) { - throw new Exception(SR.ProfilerConnectionNotFound); + await requestContext.SendError(new Exception(SR.StartSessionFailed(e.Message))); } - } - catch (Exception e) - { - await requestContext.SendError(new Exception(SR.StartSessionFailed(e.Message))); - } + }); } /// @@ -198,25 +204,47 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal async Task HandleStopProfilingRequest(StopProfilingParams parameters, RequestContext requestContext) { - try + await Task.Run(async () => { - ProfilerSession session; - monitor.StopMonitoringSession(parameters.OwnerUri, out session); + try + { + ProfilerSession session; + monitor.StopMonitoringSession(parameters.OwnerUri, out session); - if (session != null) - { - session.XEventSession.Stop(); - await requestContext.SendResult(new StopProfilingResult{}); + if (session != null) + { + // Occasionally we might see the InvalidOperationException due to a read is + // in progress, add the following retry logic will solve the problem. + int remainingAttempts = 3; + while (true) + { + try + { + session.XEventSession.Stop(); + await requestContext.SendResult(new StopProfilingResult { }); + break; + } + catch (InvalidOperationException) + { + remainingAttempts--; + if (remainingAttempts == 0) + { + throw; + } + Thread.Sleep(500); + } + } + } + else + { + throw new Exception(SR.SessionNotFound); + } } - else + catch (Exception e) { - throw new Exception(SR.SessionNotFound); + await requestContext.SendError(new Exception(SR.StopSessionFailed(e.Message))); } - } - catch (Exception e) - { - await requestContext.SendError(new Exception(SR.StopSessionFailed(e.Message))); - } + }); } /// @@ -224,16 +252,19 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal async Task HandlePauseProfilingRequest(PauseProfilingParams parameters, RequestContext requestContext) { - try + await Task.Run(async () => { - monitor.PauseViewer(parameters.OwnerUri); + try + { + monitor.PauseViewer(parameters.OwnerUri); - await requestContext.SendResult(new PauseProfilingResult{}); - } - catch (Exception e) - { - await requestContext.SendError(new Exception(SR.PauseSessionFailed(e.Message))); - } + await requestContext.SendResult(new PauseProfilingResult { }); + } + catch (Exception e) + { + await requestContext.SendError(new Exception(SR.PauseSessionFailed(e.Message))); + } + }); } /// @@ -241,28 +272,31 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal async Task HandleGetXEventSessionsRequest(GetXEventSessionsParams parameters, RequestContext requestContext) { - try - { - var result = new GetXEventSessionsResult(); - ConnectionInfo connInfo; - ConnectionServiceInstance.TryFindConnection( - parameters.OwnerUri, - out connInfo); - if (connInfo == null) + await Task.Run(async () => + { + try { - await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound)); + var result = new GetXEventSessionsResult(); + ConnectionInfo connInfo; + ConnectionServiceInstance.TryFindConnection( + parameters.OwnerUri, + out connInfo); + if (connInfo == null) + { + await requestContext.SendError(new Exception(SR.ProfilerConnectionNotFound)); + } + else + { + List sessions = GetXEventSessionList(parameters.OwnerUri, connInfo); + result.Sessions = sessions; + await requestContext.SendResult(result); + } } - else + catch (Exception e) { - List sessions = GetXEventSessionList(parameters.OwnerUri, connInfo); - result.Sessions = sessions; - await requestContext.SendResult(result); + await requestContext.SendError(e); } - } - catch (Exception e) - { - await requestContext.SendError(e); - } + }); } /// @@ -273,21 +307,22 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler /// internal List GetXEventSessionList(string ownerUri, ConnectionInfo connInfo) { - var sqlConnection = ConnectionService.OpenSqlConnection(connInfo); - SqlStoreConnection connection = new SqlStoreConnection(sqlConnection); - BaseXEStore store = CreateXEventStore(connInfo, connection); + var sqlConnection = ConnectionService.OpenSqlConnection(connInfo); + SqlStoreConnection connection = new SqlStoreConnection(sqlConnection); + BaseXEStore store = CreateXEventStore(connInfo, connection); // get session names from the session list - List results = store.Sessions.Aggregate(new List(), (result, next) => { - result.Add(next.Name); - return result; - } ); + List results = store.Sessions.Aggregate(new List(), (result, next) => + { + result.Add(next.Name); + return result; + }); return results; } private static BaseXEStore CreateXEventStore(ConnectionInfo connInfo, SqlStoreConnection connection) - { + { BaseXEStore store = null; if (connInfo.IsCloud) { @@ -348,12 +383,13 @@ namespace Microsoft.SqlTools.ServiceLayer.Profiler { throw new Exception(SR.SessionAlreadyExists(sessionName)); } - - var statement = createStatement.Replace("{sessionName}",sessionName); + + var statement = createStatement.Replace("{sessionName}", sessionName); connection.ServerConnection.ExecuteNonQuery(statement); store.Refresh(); session = store.Sessions[sessionName]; - if (session == null){ + if (session == null) + { throw new Exception(SR.SessionNotFound); } if (!session.IsRunning)