private static void UpdateSubProgress([NotNull] VerificationResponse responseMsg, [NotNull] SubResponse subResponse) { VerificationProgressMsg progressMsg = responseMsg.Progress; if (progressMsg == null) { return; } if (subResponse.Status != ServiceCallStatus.Running && subResponse.Status != ServiceCallStatus.Finished) { subResponse.CancellationMessage = progressMsg.Message; } // TODO: More stuff? Box? subResponse.ProgressTotal = progressMsg.OverallProgressTotalSteps; subResponse.ProgressCurrent = progressMsg.OverallProgressCurrentStep; if (progressMsg.CurrentBox != null) { subResponse.CurrentBox = progressMsg.CurrentBox; } }
private bool UpdateOverallProgress(SubResponse response) { // The 'slowest' wins: if (response.ProgressTotal == 0) { return(false); } SubResponse slowest = GetSlowestResponse(_tasks.Values); OverallProgressCurrent = slowest.ProgressCurrent; OverallProgressTotal = slowest.ProgressTotal; return(response == slowest); }
private static SubResponse GetSlowestResponse(ICollection <SubResponse> subResponses) { double slowest = double.MaxValue; SubResponse result = null; foreach (SubResponse subResponse in subResponses) { if (subResponse.ProgressRatio < slowest) { result = subResponse; slowest = subResponse.ProgressRatio; } } return(result); }
private async Task <bool> VerifyAsync( [NotNull] QualityVerificationGrpc.QualityVerificationGrpcClient rpcClient, [NotNull] VerificationRequest request, [NotNull] SubResponse subResponse, CancellationTokenSource cancellationSource) { using (var call = rpcClient.VerifyQuality(request)) { while (await call.ResponseStream.MoveNext(cancellationSource.Token)) { VerificationResponse responseMsg = call.ResponseStream.Current; HandleResponseMsg(responseMsg, subResponse); } } return(true); }
private void HandleResponseMsg([NotNull] VerificationResponse responseMsg, [NotNull] SubResponse subResponse) { foreach (IssueMsg issueMessage in responseMsg.Issues) { subResponse.Issues.Add(issueMessage); } subResponse.Status = (ServiceCallStatus)responseMsg.ServiceCallStatus; UpdateSubProgress(responseMsg, subResponse); if (responseMsg.QualityVerification != null) { subResponse.VerificationMsg = responseMsg.QualityVerification; } LogProgress(responseMsg.Progress); }
private static bool TryTakeCompletedRun( IDictionary <Task <bool>, SubResponse> tasks, out Task <bool> task, out SubResponse subVerification) { KeyValuePair <Task <bool>, SubResponse> keyValuePair = tasks.FirstOrDefault(kvp => kvp.Key.IsCompleted); // NOTE: 'Default' is an empty keyValuePair struct task = keyValuePair.Key; subVerification = keyValuePair.Value; if (task == null) { return(false); } return(tasks.Remove(task)); }
private bool DrainIssues(SubResponse fromSubVerification) { if (fromSubVerification == null) { return(false); } bool drained = false; IssueMsg issueMsg; if (fromSubVerification.Issues.TryTake(out issueMsg)) { // This is the global issue collection that will be sent on progress: _issueCollection.Add(issueMsg); drained = true; } return(drained); }
private void ProcessFinalResult(Task <bool> task, SubResponse subVerification) { if (task.IsFaulted) { _msg.WarnFormat("Sub-verification has faulted: {0}", subVerification); CancellationTokenSource.Cancel(); CancellationMessage = task.Exception?.InnerException?.Message; } if (!string.IsNullOrEmpty(subVerification.CancellationMessage)) { CancellationMessage = subVerification.CancellationMessage; } QualityVerificationMsg verificationMsg = subVerification.VerificationMsg; if (verificationMsg != null) { AddVerification(verificationMsg, QualityVerification); } DrainIssues(subVerification); }
public void Execute(IEnumerable <ITest> tests, AreaOfInterest areaOfInterest, CancellationTokenSource cancellationTokenSource) { Assert.NotNull(QualitySpecification, "QualitySpecification has not been initialized."); Assert.NotNull(TestAssembler, "TestAssembler has not been initialized."); StartVerification(QualityVerification); CancellationTokenSource = cancellationTokenSource; IList <IList <QualityCondition> > qcGroups = TestAssembler.BuildQualityConditionGroups(tests.ToList(), areaOfInterest, FilterTableRowsUsingRelatedGeometry, _originalRequest.MaxParallelProcessing); foreach (IList <QualityCondition> qcGroup in qcGroups) { if (qcGroup.Count == 0) { continue; } VerificationRequest subRequest = CreateSubRequest(_originalRequest, QualitySpecification, qcGroup); SubResponse subResponse = new SubResponse(); Task <bool> task = Task.Run( async() => await VerifyAsync(_qaClient, subRequest, subResponse, CancellationTokenSource), CancellationTokenSource.Token); // Process the messages even though the foreground thread is blocking/busy processing results task.ConfigureAwait(false); _tasks.Add(Assert.NotNull(task), subResponse); Thread.Sleep(50); } while (_tasks.Count > 0) { if (TryTakeCompletedRun(_tasks, out Task <bool> task, out SubResponse subResponse)) { ProcessFinalResult(task, subResponse); _msg.InfoFormat("Remaining work unit verifications: {0}", _tasks.Count); } else { // Process intermediate errors (might need de-duplication or other manipulation in the future) bool reportProgress = false; foreach (SubResponse response in _tasks.Values) { if (DrainIssues(response)) { reportProgress = true; } if (UpdateOverallProgress(response)) { reportProgress = true; } } if (reportProgress) { var eventArgs = new VerificationProgressEventArgs( VerificationProgressType.ProcessParallel, OverallProgressCurrent, OverallProgressTotal); eventArgs.Tag = "TODO"; Progress?.Invoke(this, eventArgs); } } Thread.Sleep(100); } EndVerification(QualityVerification); }