Beispiel #1
0
        /// <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);
            }
        }