Example #1
0
        /// <summary>
        /// Creates a new <see cref="SubscriberConnection"/> instance.
        /// </summary>
        /// <param name="parent">Parent data publisher.</param>
        /// <param name="clientID">Client ID of associated connection.</param>
        /// <param name="serverCommandChannel"><see cref="TcpServer"/> command channel used to lookup connection information.</param>
        /// <param name="clientCommandChannel"><see cref="TcpClient"/> command channel used to lookup connection information.</param>
        public SubscriberConnection(DataPublisher parent, Guid clientID, IServer serverCommandChannel, IClient clientCommandChannel)
        {
            m_parent               = parent;
            ClientID               = clientID;
            ServerCommandChannel   = serverCommandChannel;
            ClientCommandChannel   = clientCommandChannel;
            m_subscriberID         = clientID;
            m_keyIVs               = null;
            m_cipherIndex          = 0;
            CacheUpdateLock        = new();
            PendingCacheUpdateLock = new();

            // Setup ping timer
            m_pingTimer           = Common.TimerScheduler.CreateTimer(5000);
            m_pingTimer.AutoReset = true;
            m_pingTimer.Elapsed  += PingTimer_Elapsed;
            m_pingTimer.Start();

            // Setup reconnect timer
            m_reconnectTimer           = Common.TimerScheduler.CreateTimer(1000);
            m_reconnectTimer.AutoReset = false;
            m_reconnectTimer.Elapsed  += ReconnectTimer_Elapsed;

            LookupEndPointInfo(clientID, GetCommandChannelSocket().RemoteEndPoint as IPEndPoint, ref m_ipAddress, ref m_hostName, ref m_connectionID);
        }
Example #2
0
        /// <summary>
        /// Creates a new <see cref="DataGapRecoverer"/>.
        /// </summary>
        public DataGapRecoverer()
        {
            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);
            Log.InitialStackMessages = Log.InitialStackMessages.Union("ComponentName", GetType().Name);

            m_dataGapRecoveryCompleted = new ManualResetEventSlim(true);

            m_recoveryStartDelay  = DefaultRecoveryStartDelay;
            m_minimumRecoverySpan = DefaultMinimumRecoverySpan;
            m_maximumRecoverySpan = DefaultMaximumRecoverySpan;
            StartRecoveryBuffer   = DefaultStartRecoveryBuffer;
            EndRecoveryBuffer     = DefaultEndRecoveryBuffer;

            string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath));

            if (Directory.Exists(loggingPath))
            {
                m_loggingPath = loggingPath;
            }

            m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false);
            m_subscriptionInfo.FilterExpression         = DefaultFilterExpression;
            m_subscriptionInfo.ProcessingInterval       = DefaultRecoveryProcessingInterval;
            m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution;

            m_dataStreamMonitor           = Common.TimerScheduler.CreateTimer((int)(DefaultDataMonitoringInterval * 1000.0D));
            m_dataStreamMonitor.Elapsed  += DataStreamMonitor_Elapsed;
            m_dataStreamMonitor.AutoReset = true;
            m_dataStreamMonitor.Enabled   = false;
        }
Example #3
0
        /// <summary>
        /// Constructs a new instance of the <see cref="OutputAdapterBase"/>.
        /// </summary>
        protected OutputAdapterBase()
        {
            m_metadataRefreshOperation = new LongSynchronizedOperation(ExecuteMetadataRefresh)
            {
                IsBackground = true
            };

            m_measurementQueue = ProcessQueue <IMeasurement> .CreateRealTimeQueue(ProcessMeasurements);

            m_measurementQueue.ProcessException += m_measurementQueue_ProcessException;

            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer          = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled   = false;

            // We monitor total number of unarchived measurements every 5 seconds - this is a useful statistic to monitor, if
            // total number of unarchived measurements gets very large, measurement archival could be falling behind
            m_monitorTimer          = Common.TimerScheduler.CreateTimer(5000);
            m_monitorTimer.Elapsed += m_monitorTimer_Elapsed;

            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Enabled   = false;
        }
        public RandomDataViewModel(
            // This will be a unique IUpbeatService created and injected by the IUpbeatStack specifically for this ViewModel.
            IUpbeatService upbeatService,
            // This will be an injected transient instance of a Random service.
            Random random,
            // This is a shared singleton service.
            SharedTimer sharedTimer)
        {
            _upbeatService = upbeatService ?? throw new ArgumentNullException(nameof(upbeatService));
            _random        = random ?? throw new ArgumentNullException(nameof(random));
            _sharedTimer   = sharedTimer ?? throw new ArgumentNullException(nameof(sharedTimer));

            _sharedTimer.Ticked += SharedTimerTicked;

            // DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
            OpenPositionedPopupCommand = new DelegateCommand <Func <Point> >(
                // Create a Parameters object for a ViewModel and pass it to the IUpbeatStack using OpenViewModel. The IUpbeatStack will use the configured mappings to create the appropriate ViewModel from the Parameters type.
                pointGetter => _upbeatService.OpenViewModel(
                    new PopupViewModel.Parameters
            {
                Message = "This popup appears on top of\nthe button that opened it.",
                // The pointGetter parameter is a Func<Point> created by the View that will return the position within the window of the control that executed this command. See the bindings in View\RandomDataControl.xaml for details on how to bind a pointGetter() as a CommandParameter.
                Position = pointGetter(),
            }));
            RefreshDataCommand = new DelegateCommand(RefreshData);

            Data = new ReadOnlyObservableCollection <KeyValuePair <string, string> >(_data);

            for (var i = 0; i < 100; i++)
            {
                _data.Add(CreateRandomKeyValuePair());
            }
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="UnsynchronizedClientSubscription"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        m_parent = null;

                        // Dispose base time rotation timer
                        if ((object)m_baseTimeRotationTimer != null)
                        {
                            m_baseTimeRotationTimer.Dispose();
                            m_baseTimeRotationTimer = null;
                        }

                        // Dispose Iaon session
                        this.DisposeTemporalSession(ref m_iaonSession);
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
Example #6
0
        public MenuViewModel(
            // This will be a unique IUpbeatService created and injected by the IUpbeatStack specifically for this ViewModel.
            IUpbeatService upbeatService,
            // This ViewModel requires an async delegate to be provided, so it can start closing the application.
            Func <Task> closeApplicationCallbackAsync,
            // This is a shared singleton service.
            SharedTimer sharedTimer)
        {
            _upbeatService = upbeatService ?? throw new NullReferenceException(nameof(upbeatService));
            _            = closeApplicationCallbackAsync ?? throw new NullReferenceException(nameof(closeApplicationCallbackAsync));
            _sharedTimer = sharedTimer ?? throw new NullReferenceException(nameof(sharedTimer));

            _sharedTimer.Ticked += SharedTimerTicked;

            // DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
            ExitCommand           = new DelegateCommand(closeApplicationCallbackAsync);
            OpenRandomDataCommand = new DelegateCommand(
                () =>
            {
                // Create a Parameters object for a ViewModel and pass it to the IUpbeatStack using OpenViewModel. The IUpbeatStack will use the configured mappings to create the appropriate ViewModel from the Parameters type.
                _upbeatService.OpenViewModel(new RandomDataViewModel.Parameters());
                // Since this is Side Menu, it can close after the requested ViewModel is opened.
                _upbeatService.Close();
            });
            OpenSharedListCommand = new DelegateCommand(
                () =>
            {
                _upbeatService.OpenViewModel(new SharedListViewModel.Parameters());
                _upbeatService.Close();
            });
        }
Example #7
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="DataGapRecoverer"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if ((object)m_dataGapRecoveryCompleted != null)
                        {
                            // Signal any waiting threads
                            m_abnormalTermination = true;
                            m_dataGapRecoveryCompleted.Set();
                            m_dataGapRecoveryCompleted.Dispose();
                        }

                        if ((object)m_dataStreamMonitor != null)
                        {
                            m_dataStreamMonitor.Elapsed -= DataStreamMonitor_Elapsed;
                            m_dataStreamMonitor.Dispose();
                            m_dataStreamMonitor = null;
                        }

                        if ((object)m_dataGapLogProcessor != null)
                        {
                            m_dataGapLogProcessor.Dispose();
                            m_dataGapLogProcessor = null;
                        }

                        if ((object)m_dataGapLog != null)
                        {
                            m_dataGapLog.ProcessException -= Common_ProcessException;
                            m_dataGapLog.Dispose();
                            m_dataGapLog = null;
                        }

                        if ((object)m_temporalSubscription != null)
                        {
                            m_temporalSubscription.StatusMessage         -= Common_StatusMessage;
                            m_temporalSubscription.ProcessException      -= Common_ProcessException;
                            m_temporalSubscription.ConnectionEstablished -= TemporalSubscription_ConnectionEstablished;
                            m_temporalSubscription.ConnectionTerminated  -= TemporalSubscription_ConnectionTerminated;
                            m_temporalSubscription.NewMeasurements       -= TemporalSubscription_NewMeasurements;
                            m_temporalSubscription.ProcessingComplete    -= TemporalSubscription_ProcessingComplete;
                            m_temporalSubscription.Dispose();
                            m_temporalSubscription = null;
                        }
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.

                    if ((object)Disposed != null)
                    {
                        Disposed(this, EventArgs.Empty);
                    }
                }
            }
        }
Example #8
0
        public BottomViewModel(
            // This will be a unique IUpbeatService created and injected by the IUpbeatStack specifically for this ViewModel.
            IUpbeatService upbeatService,
            // This is a shared singleton service.
            SharedTimer sharedTimer)
        {
            _upbeatService = upbeatService ?? throw new NullReferenceException(nameof(upbeatService));
            _sharedTimer   = sharedTimer ?? throw new NullReferenceException(nameof(sharedTimer));

            // Registering a CloseCallback allows the ViewModel to prevent itself from closing. For example: if there is unsaved work. This can also completely prevent the application from shutting down. CloseCallbacks can be either async or non-async methods/lambdas.
            _upbeatService.RegisterCloseCallback(AskBeforeClosingAsync);

            _sharedTimer.Ticked += SharedTimerTicked;

            // DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
            OpenMenuCommand = new DelegateCommand(
                // Create a Parameters object for a ViewModel and pass it to the IUpbeatStack using OpenViewModel. The IUpbeatStack will use the configured mappings to create the appropriate ViewModel from the Parameters type.
                () => _upbeatService.OpenViewModel(
                    new MenuViewModel.Parameters()));
            OpenSharedListCommand = new DelegateCommand(
                () => _upbeatService.OpenViewModel(
                    new SharedListViewModel.Parameters()));
            OpenRandomDataCommand = new DelegateCommand(
                () => _upbeatService.OpenViewModel(
                    new RandomDataViewModel.Parameters()));
        }
Example #9
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="ClientConnection"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if ((object)m_pingTimer != null)
                        {
                            m_pingTimer.Elapsed -= m_pingTimer_Elapsed;
                            m_pingTimer.Dispose();
                            m_pingTimer = null;
                        }

                        if ((object)m_reconnectTimer != null)
                        {
                            m_reconnectTimer.Elapsed -= m_reconnectTimer_Elapsed;
                            m_reconnectTimer.Dispose();
                            m_reconnectTimer = null;
                        }

                        DataChannel      = null;
                        m_commandChannel = null;
                        m_ipAddress      = null;
                        m_subscription   = null;
                        m_parent         = null;
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.
                }
            }
        }
        /// <summary>
        /// Initializes <see cref="SynchronizedClientSubscription"/>.
        /// </summary>
        public override void Initialize()
        {
            MeasurementKey[] inputMeasurementKeys;
            string           setting;

            if (Settings.TryGetValue("inputMeasurementKeys", out setting))
            {
                // IMPORTANT: The allowSelect argument of ParseInputMeasurementKeys must be null
                //            in order to prevent SQL injection via the subscription filter expression
                inputMeasurementKeys   = AdapterBase.ParseInputMeasurementKeys(DataSource, false, setting);
                m_requestedInputFilter = setting;

                // IMPORTANT: We need to remove the setting before calling base.Initialize()
                //            or else we will still be subject to SQL injection
                Settings.Remove("inputMeasurementKeys");
            }
            else
            {
                inputMeasurementKeys   = new MeasurementKey[0];
                m_requestedInputFilter = null;
            }

            base.Initialize();

            // Set the InputMeasurementKeys and UsePrecisionTimer properties after calling
            // base.Initialize() so that the base class does not overwrite our settings
            InputMeasurementKeys = inputMeasurementKeys;
            UsePrecisionTimer    = false;

            if (Settings.TryGetValue("bufferBlockRetransmissionTimeout", out setting))
            {
                m_bufferBlockRetransmissionTimeout = double.Parse(setting);
            }
            else
            {
                m_bufferBlockRetransmissionTimeout = 5.0D;
            }

            if (Settings.TryGetValue("requestNaNValueFilter", out setting))
            {
                m_isNaNFiltered = m_parent.AllowNaNValueFilter && setting.ParseBoolean();
            }
            else
            {
                m_isNaNFiltered = false;
            }

            m_bufferBlockRetransmissionTimer           = Common.TimerScheduler.CreateTimer((int)(m_bufferBlockRetransmissionTimeout * 1000.0D));
            m_bufferBlockRetransmissionTimer.AutoReset = false;
            m_bufferBlockRetransmissionTimer.Elapsed  += BufferBlockRetransmissionTimer_Elapsed;

            // Handle temporal session initialization
            if (this.TemporalConstraintIsDefined())
            {
                m_iaonSession = this.CreateTemporalSession();
            }
        }
Example #11
0
        public void SharedTimer_Disposed_NoCallback()
        {
            var timerSet = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                timer.Register(_ => timerSet.Set(), null);
            }
            Assert.False(timerSet.WaitOne(100));
        }
Example #12
0
        public void SharedTimer_DisposeRegistrationQuickly_NoCallback()
        {
            var timerSet = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                IDisposable cleanup = timer.Register(_ => timerSet.Set(), null);
                cleanup.Dispose();
                Assert.False(timerSet.WaitOne(100));
            }
        }
Example #13
0
 public void SharedTimer_Register_CallbackInvoked()
 {
     var timerSet = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         using (IDisposable cleanup = timer.Register(_ => timerSet.Set(), null))
         {
             Assert.NotNull(cleanup);
             Assert.True(timerSet.WaitOne(100));
         }
     }
 }
Example #14
0
        public void SharedTimer_Register_CallbackInvoked()
        {
            var timerSet = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                using (IDisposable cleanup = timer.Register(_ => timerSet.Set(), null))
                {
                    Assert.NotNull(cleanup);
                    Assert.True(timerSet.WaitOne(100));
                }
            }
        }
Example #15
0
 /// <summary>
 /// Initializes a new instance of the <see cref="FileClient"/> class.
 /// </summary>
 /// <param name="connectString">Connect string of the <see cref="FileClient"/>. See <see cref="DefaultConnectionString"/> for format.</param>
 public FileClient(string connectString) : base(TransportProtocol.File, connectString)
 {
     m_autoRepeat                = DefaultAutoRepeat;
     m_receiveOnDemand           = DefaultReceiveOnDemand;
     m_receiveInterval           = DefaultReceiveInterval;
     m_startingOffset            = DefaultStartingOffset;
     FileOpenMode                = DefaultFileOpenMode;
     FileShareMode               = DefaultFileShareMode;
     m_fileAccessMode            = DefaultFileAccessMode;
     m_fileClient                = new TransportProvider <FileStream>();
     m_receiveDataTimer          = s_timerScheduler.CreateTimer();
     m_receiveDataTimer.Elapsed += m_receiveDataTimer_Elapsed;
 }
Example #16
0
        /// <summary>
        /// Constructs a new instance of the <see cref="InputAdapterBase"/>.
        /// </summary>
        protected InputAdapterBase()
        {
            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer          = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled   = false;
        }
Example #17
0
        public void SharedTimer_OneCallbackThrows_OtherCallbacksInvoked()
        {
            var timerSet0 = new ManualResetEvent(false);
            var timerSet1 = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                timer.Register(_ => timerSet0.Set(), null);
                timer.Register(_ => { throw new InvalidOperationException(); }, null);
                timer.Register(_ => timerSet1.Set(), null);
                Assert.True(timerSet0.WaitOne(500));
                Assert.True(timerSet1.WaitOne(500));
            }
        }
Example #18
0
        public PopupViewModel(
            // These are the parameters the parent used when opening this ViewModel. The IUpbeatService can inject the Parameters object into this constructor to pass initialization data or callbacks.
            Parameters parameters,
            // This is a shared singleton service.
            SharedTimer sharedTimer)
        {
            _            = parameters ?? throw new NullReferenceException(nameof(parameters));
            _sharedTimer = sharedTimer ?? throw new ArgumentNullException(nameof(sharedTimer));

            Message   = parameters.Message;
            XPosition = parameters.Position.X;
            YPosition = parameters.Position.Y;

            _sharedTimer.Ticked += SharedTimerTicked;
        }
Example #19
0
 public void SharedTimer_RegisterState_CallbackInvokedWithState()
 {
     var myState = new object();
     bool? correctState = null;
     var timerSet = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         timer.Register(state =>
         {
             correctState = (myState == state);
             timerSet.Set();
         }, myState);
         Assert.True(timerSet.WaitOne(100));
         Assert.True(correctState.Value);
     }
 }
Example #20
0
        public void SharedTimer_DisposeOne_OtherCallbacksInvoked()
        {
            var timerSet0 = new ManualResetEvent(false);
            var timerSet1 = new ManualResetEvent(false);
            var timerSet2 = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                IDisposable dispose0 = timer.Register(_ => timerSet0.Set(), null);
                IDisposable dispose1 = timer.Register(_ => timerSet1.Set(), null);
                IDisposable dispose2 = timer.Register(_ => timerSet2.Set(), null);
                dispose1.Dispose();
                Assert.True(timerSet0.WaitOne(100));
                Assert.True(timerSet2.WaitOne(100));
                Assert.False(timerSet1.WaitOne(100));
            }
        }
Example #21
0
        public void SharedTimer_RegisterState_CallbackInvokedWithState()
        {
            var  myState      = new object();
            bool?correctState = null;
            var  timerSet     = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                timer.Register(state =>
                {
                    correctState = (myState == state);
                    timerSet.Set();
                }, myState);
                Assert.True(timerSet.WaitOne(100));
                Assert.True(correctState.Value);
            }
        }
 public ConfirmPopupViewModel
 // This will be a unique IUpbeatService created and injected by the IUpbeatStack specifically for this ViewModel.
     (IUpbeatService upbeatService,
     // These are the parameters the parent used when opening this ViewModel. The IUpbeatService can inject the Parameters object into this constructor to pass initialization data or callbacks.
     Parameters parameters,
     // This is a shared singleton service.
     SharedTimer sharedTimer)
     : base(parameters, sharedTimer)
 {
     // DelegateCommand is a common convenience ICommand implementation to call methods or lambda expressions when the command is executed. It supports both async and non-async methods/lambdas.
     ConfirmCommand = new DelegateCommand(
         () =>
     {
         parameters?.ConfirmCallback?.Invoke();
         // Will close this ViewModel.
         upbeatService.Close();
     });
 }
Example #23
0
        public SharedListViewModel(
            // This will be a unique IUpbeatService created and injected by the IUpbeatStack for this ViewModel and child ViewModels.
            IUpbeatService upbeatService,
            // This is a scoped service shared between this ViewModel and other ViewModel or scoped/transient service dependencies.
            SharedList sharedList,
            // This is a shared singleton service.
            SharedTimer sharedTimer,
            // This is a child ViewModel, which can help with separating concerns and keep ViewModels from being too complicated. Child ViewModels share an IUpbeatService and any scoped services with their parents.
            SharedListDataViewModel sharedListDataViewModel)
        {
            _upbeatService          = upbeatService ?? throw new NullReferenceException(nameof(upbeatService));
            _sharedTimer            = sharedTimer ?? throw new NullReferenceException(nameof(sharedTimer));
            _sharedList             = sharedList ?? throw new ArgumentNullException(nameof(sharedList));
            SharedListDataViewModel = sharedListDataViewModel ?? throw new ArgumentNullException(nameof(sharedListDataViewModel));

            _sharedTimer.Ticked     += SharedTimerTicked;
            _sharedList.StringAdded += SharedListStringAdded;

            CloseCommand = new DelegateCommand(_upbeatService.Close);
        }
Example #24
0
 public void SharedTimer_Register5_CallbacksInvoked()
 {
     var timerSet0 = new ManualResetEvent(false);
     var timerSet1 = new ManualResetEvent(false);
     var timerSet2 = new ManualResetEvent(false);
     var timerSet3 = new ManualResetEvent(false);
     var timerSet4 = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         timer.Register(_ => timerSet0.Set(), null);
         timer.Register(_ => timerSet1.Set(), null);
         timer.Register(_ => timerSet2.Set(), null);
         timer.Register(_ => timerSet3.Set(), null);
         timer.Register(_ => timerSet4.Set(), null);
         Assert.True(timerSet0.WaitOne(100));
         Assert.True(timerSet1.WaitOne(100));
         Assert.True(timerSet2.WaitOne(100));
         Assert.True(timerSet3.WaitOne(100));
         Assert.True(timerSet4.WaitOne(100));
     }
 }
Example #25
0
        public void SharedTimer_Register5_CallbacksInvoked()
        {
            var timerSet0 = new ManualResetEvent(false);
            var timerSet1 = new ManualResetEvent(false);
            var timerSet2 = new ManualResetEvent(false);
            var timerSet3 = new ManualResetEvent(false);
            var timerSet4 = new ManualResetEvent(false);

            using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
            {
                timer.Register(_ => timerSet0.Set(), null);
                timer.Register(_ => timerSet1.Set(), null);
                timer.Register(_ => timerSet2.Set(), null);
                timer.Register(_ => timerSet3.Set(), null);
                timer.Register(_ => timerSet4.Set(), null);
                Assert.True(timerSet0.WaitOne(100));
                Assert.True(timerSet1.WaitOne(100));
                Assert.True(timerSet2.WaitOne(100));
                Assert.True(timerSet3.WaitOne(100));
                Assert.True(timerSet4.WaitOne(100));
            }
        }
Example #26
0
 /// <summary>
 /// Releases the unmanaged resources used by the <see cref="InputAdapterBase"/> object and optionally releases the managed resources.
 /// </summary>
 /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
 protected override void Dispose(bool disposing)
 {
     if (!m_disposed)
     {
         try
         {
             if (disposing)
             {
                 if (m_connectionTimer != null)
                 {
                     m_connectionTimer.Elapsed -= m_connectionTimer_Elapsed;
                     m_connectionTimer.Dispose();
                 }
                 m_connectionTimer = null;
             }
         }
         finally
         {
             m_disposed = true;          // Prevent duplicate dispose.
             base.Dispose(disposing);    // Call base class Dispose().
         }
     }
 }
Example #27
0
        /// <summary>
        /// Creates a new <see cref="DataGapRecoverer"/>.
        /// </summary>
        public DataGapRecoverer()
        {
            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);
            Log.InitialStackMessages = Log.InitialStackMessages.Union("ComponentName", GetType().Name);

            m_dataGapRecoveryCompleted = new(true);

            m_recoveryStartDelay  = DefaultRecoveryStartDelay;
            m_minimumRecoverySpan = DefaultMinimumRecoverySpan;
            m_maximumRecoverySpan = DefaultMaximumRecoverySpan;
            StartRecoveryBuffer   = DefaultStartRecoveryBuffer;
            EndRecoveryBuffer     = DefaultEndRecoveryBuffer;

            string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath));

            if (Directory.Exists(loggingPath))
            {
                m_loggingPath = loggingPath;
            }

            m_subscriptionInfo = new()
            {
                FilterExpression         = DefaultFilterExpression,
                ProcessingInterval       = DefaultRecoveryProcessingInterval,
                UseMillisecondResolution = DefaultUseMillisecondResolution
            };

            m_dataStreamMonitor           = Common.TimerScheduler.CreateTimer((int)(DefaultDataMonitoringInterval * 1000.0D));
            m_dataStreamMonitor.Elapsed  += DataStreamMonitor_Elapsed;
            m_dataStreamMonitor.AutoReset = true;
            m_dataStreamMonitor.Enabled   = false;
        }

        /// <summary>
        /// Releases the unmanaged resources before the <see cref="DataGapRecoverer"/> object is reclaimed by <see cref="GC"/>.
        /// </summary>
        ~DataGapRecoverer() => Dispose(false);
Example #28
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="OutputAdapterBase"/> object and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if (m_connectionTimer != null)
                        {
                            m_connectionTimer.Elapsed -= m_connectionTimer_Elapsed;
                            m_connectionTimer.Dispose();
                        }
                        m_connectionTimer = null;

                        if (m_monitorTimer != null)
                        {
                            m_monitorTimer.Elapsed -= m_monitorTimer_Elapsed;
                            m_monitorTimer.Dispose();
                        }
                        m_monitorTimer = null;

                        if (m_measurementQueue != null)
                        {
                            m_measurementQueue.ProcessException -= m_measurementQueue_ProcessException;
                            m_measurementQueue.Dispose();
                        }
                        m_measurementQueue = null;
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
Example #29
0
 public void SharedTimer_DisposeOne_OtherCallbacksInvoked()
 {
     var timerSet0 = new ManualResetEvent(false);
     var timerSet1 = new ManualResetEvent(false);
     var timerSet2 = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         IDisposable dispose0 = timer.Register(_ => timerSet0.Set(), null);
         IDisposable dispose1 = timer.Register(_ => timerSet1.Set(), null);
         IDisposable dispose2 = timer.Register(_ => timerSet2.Set(), null);
         dispose1.Dispose();
         Assert.True(timerSet0.WaitOne(100));
         Assert.True(timerSet2.WaitOne(100));
         Assert.False(timerSet1.WaitOne(100));
     }
 }
Example #30
0
 public void SharedTimer_OneCallbackThrows_OtherCallbacksInvoked()
 {
     var timerSet0 = new ManualResetEvent(false);
     var timerSet1 = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         timer.Register(_ => timerSet0.Set(), null);
         timer.Register(_ => { throw new InvalidOperationException(); }, null);
         timer.Register(_ => timerSet1.Set(), null);
         Assert.True(timerSet0.WaitOne(500));
         Assert.True(timerSet1.WaitOne(500));
     }
 }
Example #31
0
 public void SharedTimer_DisposeRegistrationQuickly_NoCallback()
 {
     var timerSet = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         IDisposable cleanup = timer.Register(_ => timerSet.Set(), null);
         cleanup.Dispose();
         Assert.False(timerSet.WaitOne(100));
     }
 }
Example #32
0
 public void SharedTimer_Disposed_NoCallback()
 {
     var timerSet = new ManualResetEvent(false);
     using (var timer = new SharedTimer(TimeSpan.FromMilliseconds(20)))
     {
         timer.Register(_ => timerSet.Set(), null);
     }
     Assert.False(timerSet.WaitOne(100));
 }
Example #33
0
        /// <summary>
        /// Creates a new <see cref="ClientConnection"/> instance.
        /// </summary>
        /// <param name="parent">Parent data publisher.</param>
        /// <param name="clientID">Client ID of associated connection.</param>
        /// <param name="commandChannel"><see cref="TcpServer"/> command channel used to lookup connection information.</param>
        public ClientConnection(DataPublisher parent, Guid clientID, IServer commandChannel)
        {
            m_parent         = parent;
            m_clientID       = clientID;
            m_commandChannel = commandChannel;
            m_subscriberID   = clientID;
            m_keyIVs         = null;
            m_cipherIndex    = 0;

            // Setup ping timer
            m_pingTimer           = Common.TimerScheduler.CreateTimer(5000);
            m_pingTimer.AutoReset = true;
            m_pingTimer.Elapsed  += m_pingTimer_Elapsed;
            m_pingTimer.Start();

            // Setup reconnect timer
            m_reconnectTimer           = Common.TimerScheduler.CreateTimer(1000);
            m_reconnectTimer.AutoReset = false;
            m_reconnectTimer.Elapsed  += m_reconnectTimer_Elapsed;

            // Attempt to lookup remote connection identification for logging purposes
            try
            {
                Socket     commandChannelSocket = GetCommandChannelSocket();
                IPEndPoint remoteEndPoint       = null;

                if ((object)commandChannel != null)
                {
                    remoteEndPoint = commandChannelSocket.RemoteEndPoint as IPEndPoint;
                }

                if ((object)remoteEndPoint != null)
                {
                    m_ipAddress = remoteEndPoint.Address;

                    if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                    {
                        m_connectionID = "[" + m_ipAddress + "]:" + remoteEndPoint.Port;
                    }
                    else
                    {
                        m_connectionID = m_ipAddress + ":" + remoteEndPoint.Port;
                    }

                    try
                    {
                        IPHostEntry ipHost = Dns.GetHostEntry(remoteEndPoint.Address);

                        if (!string.IsNullOrWhiteSpace(ipHost.HostName))
                        {
                            m_hostName     = ipHost.HostName;
                            m_connectionID = m_hostName + " (" + m_connectionID + ")";
                        }
                    }

                    // Just ignoring possible DNS lookup failures...
                    catch (ArgumentNullException)
                    {
                        // The hostNameOrAddress parameter is null.
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        // The length of hostNameOrAddress parameter is greater than 255 characters.
                    }
                    catch (ArgumentException)
                    {
                        // The hostNameOrAddress parameter is an invalid IP address.
                    }
                    catch (SocketException)
                    {
                        // An error was encountered when resolving the hostNameOrAddress parameter.
                    }
                }
            }
            catch
            {
                // At worst we'll just use the client GUID for identification
                m_connectionID = m_subscriberID == Guid.Empty ? clientID.ToString() : m_subscriberID.ToString();
            }

            if (string.IsNullOrWhiteSpace(m_connectionID))
            {
                m_connectionID = "unavailable";
            }

            if (string.IsNullOrWhiteSpace(m_hostName))
            {
                if ((object)m_ipAddress != null)
                {
                    m_hostName = m_ipAddress.ToString();
                }
                else
                {
                    m_hostName = m_connectionID;
                }
            }

            if ((object)m_ipAddress == null)
            {
                m_ipAddress = IPAddress.None;
            }
        }
        /// <summary>
        /// Initializes <see cref="UnsynchronizedClientSubscription"/>.
        /// </summary>
        public override void Initialize()
        {
            MeasurementKey[] inputMeasurementKeys;
            string           setting;

            if (Settings.TryGetValue("inputMeasurementKeys", out setting))
            {
                // IMPORTANT: The allowSelect argument of ParseInputMeasurementKeys must be null
                //            in order to prevent SQL injection via the subscription filter expression
                inputMeasurementKeys   = ParseInputMeasurementKeys(DataSource, false, setting);
                m_requestedInputFilter = setting;

                // IMPORTANT: We need to remove the setting before calling base.Initialize()
                //            or else we will still be subject to SQL injection
                Settings.Remove("inputMeasurementKeys");
            }
            else
            {
                inputMeasurementKeys   = new MeasurementKey[0];
                m_requestedInputFilter = null;
            }

            base.Initialize();

            // Set the InputMeasurementKeys property after calling base.Initialize()
            // so that the base class does not overwrite our setting
            InputMeasurementKeys = inputMeasurementKeys;

            if (!Settings.TryGetValue("publishInterval", out setting) || !double.TryParse(setting, out m_publishInterval))
            {
                m_publishInterval = -1;
            }

            if (Settings.TryGetValue("includeTime", out setting))
            {
                m_includeTime = setting.ParseBoolean();
            }
            else
            {
                m_includeTime = true;
            }

            if (Settings.TryGetValue("useMillisecondResolution", out setting))
            {
                m_useMillisecondResolution = setting.ParseBoolean();
            }
            else
            {
                m_useMillisecondResolution = false;
            }

            if (Settings.TryGetValue("requestNaNValueFilter", out setting))
            {
                m_isNaNFiltered = m_parent.AllowNaNValueFilter && setting.ParseBoolean();
            }
            else
            {
                m_isNaNFiltered = false;
            }

            if (Settings.TryGetValue("bufferBlockRetransmissionTimeout", out setting))
            {
                m_bufferBlockRetransmissionTimeout = double.Parse(setting);
            }
            else
            {
                m_bufferBlockRetransmissionTimeout = 5.0D;
            }

            if (m_parent.UseBaseTimeOffsets && m_includeTime)
            {
                m_baseTimeRotationTimer           = Common.TimerScheduler.CreateTimer(m_useMillisecondResolution ? 60000 : 420000);
                m_baseTimeRotationTimer.AutoReset = true;
                m_baseTimeRotationTimer.Elapsed  += BaseTimeRotationTimer_Elapsed;
            }

            m_bufferBlockRetransmissionTimer           = Common.TimerScheduler.CreateTimer((int)(m_bufferBlockRetransmissionTimeout * 1000.0D));
            m_bufferBlockRetransmissionTimer.AutoReset = false;
            m_bufferBlockRetransmissionTimer.Elapsed  += BufferBlockRetransmissionTimer_Elapsed;

            // Handle temporal session initialization
            if (this.TemporalConstraintIsDefined())
            {
                m_iaonSession = this.CreateTemporalSession();
            }
        }