Batch Start Notification (#169)

This change is part of the progressive results code. It will submit a notification from the service layer to indicate when execution of a batch has completed. This notification will contain the selection for batch, execution start time, and its ID. This will enable the extension to produce a header for the batch before the batch completes, in order to make it more clear to the user that execution is going on.

* Adding new event for batch start

* Unit tests

* Fixing comments as per @kevcunnane
This commit is contained in:
Benjamin Russell
2016-12-08 11:23:08 -08:00
committed by GitHub
parent ab97948005
commit 54f30887cc
7 changed files with 293 additions and 104 deletions

View File

@@ -75,7 +75,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
this.outputFileFactory = outputFileFactory;
}
#region Properties
#region Events
/// <summary>
/// Asynchronous handler for when batches are completed
@@ -88,12 +88,21 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </summary>
public event BatchAsyncEventHandler BatchCompletion;
/// <summary>
/// Event to call when the batch has started execution
/// </summary>
public event BatchAsyncEventHandler BatchStart;
/// <summary>
/// Event that will be called when the resultset has completed execution. It will not be
/// called from the Batch but from the ResultSet instance
/// </summary>
public event ResultSet.ResultSetAsyncEventHandler ResultSetCompletion;
#endregion
#region Properties
/// <summary>
/// The text of batch that will be executed
/// </summary>
@@ -175,17 +184,25 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
{
get
{
return new BatchSummary
// Batch summary with information available at start
BatchSummary summary = new BatchSummary
{
HasError = HasError,
Id = Id,
ResultSetSummaries = ResultSummaries,
Messages = ResultMessages.ToArray(),
Selection = Selection,
ExecutionElapsed = ExecutionElapsedTime,
ExecutionStart = ExecutionStartTimeStamp,
ExecutionEnd = ExecutionEndTimeStamp
ExecutionStart = ExecutionStartTimeStamp
};
// Add on extra details if we finished executing it
if (HasExecuted)
{
summary.ResultSetSummaries = ResultSummaries;
summary.Messages = ResultMessages.ToArray();
summary.ExecutionEnd = ExecutionEndTimeStamp;
summary.ExecutionElapsed = ExecutionElapsedTime;
}
return summary;
}
}
@@ -211,6 +228,12 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
throw new InvalidOperationException("Batch has already executed.");
}
// Notify that we've started execution
if (BatchStart != null)
{
await BatchStart(this);
}
try
{
// Register the message listener to *this instance* of the batch

View File

@@ -10,7 +10,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts
/// Parameters to be sent back as part of a QueryExecuteBatchCompleteEvent to indicate that a
/// batch of a query completed.
/// </summary>
public class QueryExecuteBatchCompleteParams
public class QueryExecuteBatchNotificationParams
{
/// <summary>
/// Summary of the batch that just completed
@@ -26,7 +26,14 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution.Contracts
public class QueryExecuteBatchCompleteEvent
{
public static readonly
EventType<QueryExecuteBatchCompleteParams> Type =
EventType<QueryExecuteBatchCompleteParams>.Create("query/batchComplete");
EventType<QueryExecuteBatchNotificationParams> Type =
EventType<QueryExecuteBatchNotificationParams>.Create("query/batchComplete");
}
public class QueryExecuteBatchStartEvent
{
public static readonly
EventType<QueryExecuteBatchNotificationParams> Type =
EventType<QueryExecuteBatchNotificationParams>.Create("query/batchStart");
}
}

View File

@@ -99,10 +99,15 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
/// </summary>
public event Batch.BatchAsyncEventHandler BatchCompleted;
/// <summary>
/// Event to be called when a batch starts execution.
/// </summary>
public event Batch.BatchAsyncEventHandler BatchStarted;
/// <summary>
/// Delegate type for callback when a query connection fails
/// </summary>
/// <param name="q">The query that completed</param>
/// <param name="message">Error message for the failing query</param>
public delegate Task QueryAsyncErrorEventHandler(string message);
/// <summary>
@@ -277,6 +282,7 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
// We need these to execute synchronously, otherwise the user will be very unhappy
foreach (Batch b in Batches)
{
b.BatchStart += BatchStarted;
b.BatchCompletion += BatchCompleted;
b.ResultSetCompletion += ResultSetCompleted;
await b.Execute(conn, cancellationSource.Token);

View File

@@ -443,17 +443,28 @@ namespace Microsoft.SqlTools.ServiceLayer.QueryExecution
query.QueryFailed += callback;
query.QueryConnectionException += errorCallback;
// Setup the batch completion callback
Batch.BatchAsyncEventHandler batchCallback = async b =>
// Setup the batch callbacks
Batch.BatchAsyncEventHandler batchStartCallback = async b =>
{
QueryExecuteBatchCompleteParams eventParams = new QueryExecuteBatchCompleteParams
QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams
{
BatchSummary = b.Summary,
OwnerUri = executeParams.OwnerUri
};
await requestContext.SendEvent(QueryExecuteBatchStartEvent.Type, eventParams);
};
query.BatchStarted += batchStartCallback;
Batch.BatchAsyncEventHandler batchCompleteCallback = async b =>
{
QueryExecuteBatchNotificationParams eventParams = new QueryExecuteBatchNotificationParams
{
BatchSummary = b.Summary,
OwnerUri = executeParams.OwnerUri
};
await requestContext.SendEvent(QueryExecuteBatchCompleteEvent.Type, eventParams);
};
query.BatchCompleted += batchCallback;
query.BatchCompleted += batchCompleteCallback;
// Setup the ResultSet completion callback
ResultSet.ResultSetAsyncEventHandler resultCallback = async r =>