/// <summary> /// Stop monitoring of events. /// </summary> /// <returns></returns> public async Task <StopResult> StopAsync() { // Check if already stopped. if (_cancellationTokenSource == null) { return(new StopResult()); } Interlocked.Exchange(ref _shuttingDown, 1); var endTime = DateTime.UtcNow; if (_cancellationTokenSource != null) { _cancellationTokenSource.Cancel(); _cancellationTokenSource = null; } // the stop procedure takes about a minute, so we fire and forget. StopEventProcessorClientAsync().SafeFireAndForget(e => _logger.LogError(e, "Error while stopping event monitoring.")); // Stop checkers and collect resutls. var missingTimestampsCounter = _missingTimestampsChecker.Stop(); var maxMessageProcessingDelay = _messageProcessingDelayChecker.Stop(); var maxMessageDeliveryDelay = _messageDeliveryDelayChecker.Stop(); var valueChangesPerNodeId = _valueChangeCounterPerNodeId.Stop(); var allExpectedValueChanges = true; if (_currentConfiguration.ExpectedValueChangesPerTimestamp > 0) { // TODO collect "expected" parameter as groups related to OPC UA nodes allExpectedValueChanges = valueChangesPerNodeId? .All(kvp => (_totalValueChangesCount / kvp.Value) == _currentConfiguration.ExpectedValueChangesPerTimestamp ) ?? false; _logger.LogInformation("All expected value changes received: {AllExpectedValueChanges}", allExpectedValueChanges); } var incompleteTimestamps = _missingValueChangesChecker.Stop(); var incrCheckerResult = _incrementalIntValueChecker.Stop(); var stopResult = new StopResult() { ValueChangesByNodeId = new ReadOnlyDictionary <string, int>(valueChangesPerNodeId ?? new Dictionary <string, int>()), AllExpectedValueChanges = allExpectedValueChanges, TotalValueChangesCount = _totalValueChangesCount, AllInExpectedInterval = missingTimestampsCounter == 0, StartTime = _startTime, EndTime = endTime, MaxDelayToNow = maxMessageProcessingDelay.ToString(), MaxDeliveyDuration = maxMessageDeliveryDelay.ToString(), DroppedValueCount = incrCheckerResult.DroppedValueCount, DuplicateValueCount = incrCheckerResult.DuplicateValueCount, }; return(stopResult); }
/// <summary> /// Stop monitoring of events. /// </summary> /// <returns></returns> public Task <StopResult> StopAsync() { _logger.LogInformation("StopAsync called."); var sw = Stopwatch.StartNew(); try { // Check if already stopped. if (_cancellationTokenSource == null) { return(Task.FromResult(new StopResult())); } var endTime = DateTime.UtcNow; if (_cancellationTokenSource != null) { _cancellationTokenSource.Cancel(); _cancellationTokenSource = null; } // Stop event monitoring and deregister handler. if (_clientWrapper != null) { _clientWrapper.StopProcessing(); _clientWrapper.ProcessEventAsync -= Client_ProcessEventAsync; } // Stop checkers and collect resutls. var missingTimestampsCounter = _missingTimestampsChecker.Stop(); var maxMessageProcessingDelay = _messageProcessingDelayChecker.Stop(); var maxMessageDeliveryDelay = _messageDeliveryDelayChecker.Stop(); var valueChangesPerNodeId = _valueChangeCounterPerNodeId.Stop(); var allExpectedValueChanges = true; if (_currentConfiguration.ExpectedValueChangesPerTimestamp > 0) { // TODO collect "expected" parameter as groups related to OPC UA nodes allExpectedValueChanges = valueChangesPerNodeId? .All(kvp => (_totalValueChangesCount / kvp.Value) == _currentConfiguration.ExpectedValueChangesPerTimestamp ) ?? false; _logger.LogInformation("All expected value changes received: {AllExpectedValueChanges}", allExpectedValueChanges); } var incompleteTimestamps = _missingValueChangesChecker.Stop(); var incrCheckerResult = _incrementalIntValueChecker.Stop(); var incrSequenceResult = _incrementalSequenceChecker.Stop(); var stopResult = new StopResult() { ValueChangesByNodeId = new ReadOnlyDictionary <string, int>(valueChangesPerNodeId ?? new Dictionary <string, int>()), AllExpectedValueChanges = allExpectedValueChanges, TotalValueChangesCount = _totalValueChangesCount, AllInExpectedInterval = missingTimestampsCounter == 0, StartTime = _startTime, EndTime = endTime, MaxDelayToNow = maxMessageProcessingDelay.ToString(), MaxDeliveyDuration = maxMessageDeliveryDelay.ToString(), DroppedValueCount = incrCheckerResult.DroppedValueCount, DuplicateValueCount = incrCheckerResult.DuplicateValueCount, DroppedSequenceCount = incrSequenceResult.DroppedValueCount, DuplicateSequenceCount = incrSequenceResult.DuplicateValueCount, ResetSequenceCount = incrSequenceResult.ResetsValueCount, RestartAnnouncementReceived = _restartAnnouncementReceived, }; return(Task.FromResult(stopResult)); } finally { _logger.LogInformation("StopAsync finished in {elapsed}", sw.Elapsed); } }