/// <summary>
        /// Check the write to the broker
        /// </summary>
        public void WriteCheck()
        {
            if (this.inWrite.Value || this.failed.Value)
            {
                Tracer.DebugFormat("InactivityMonitor[{0}]: is in write or already failed.", instanceId);
                return;
            }

            CompositeTaskRunner taskRunner = this.asyncTasks;

            if (!commandSent.Value)
            {
                Tracer.DebugFormat("InactivityMonitor[{0}]: No Message sent since last write check. Sending a KeepAliveInfo.", instanceId);
                if (null != this.asyncWriteTask)
                {
                    this.asyncWriteTask.IsPending = true;
                }

                if (this.monitorStarted.Value && taskRunner != null)
                {
                    taskRunner.Wakeup();
                }
            }
            else
            {
                Tracer.DebugFormat("InactivityMonitor[{0}]: Message sent since last write check. Resetting flag.", instanceId);
            }

            commandSent.Value = false;
        }
        public void TestCompositeTaskRunner()
        {
            int attempts = 0;

            CompositeTaskRunner runner = new CompositeTaskRunner();

            CountingTask task1 = new CountingTask("task1", 100);
            CountingTask task2 = new CountingTask("task2", 200);

            runner.AddTask(task1);
            runner.AddTask(task2);

            runner.Wakeup();

            while (attempts++ != 10)
            {
                Thread.Sleep(1000);

                if (task1.Count == 100 && task2.Count == 200)
                {
                    break;
                }
            }

            Assert.IsTrue(task1.Count == 100);
            Assert.IsTrue(task2.Count == 200);

            runner.RemoveTask(task1);
            runner.RemoveTask(task2);
        }
Пример #3
0
        public void CompositeTaskRunnerDoesntHoldLockWhileCallingIterate()
        {
            object lockObj = new object();

            // Start a task running that takes a shared lock during it's iterate.
            CompositeTaskRunner runner = new CompositeTaskRunner();

            runner.AddTask(new LockingTask(lockObj));

            // Start a separate thread that holds that same lock whilst manipulating the CompositeTaskRunner (See InactivityMonitor for real example).
            AutoResetEvent resetEvent = new AutoResetEvent(false);

            ThreadPool.QueueUserWorkItem(_ =>
            {
                for (int i = 0; i < 10000; i++)
                {
                    lock (lockObj)
                    {
                        var countingTask = new CountingTask("task1", 100);
                        runner.AddTask(countingTask);
                        runner.RemoveTask(countingTask);
                    }
                }

                resetEvent.Set();
            });

            // Wait for the second thread to finish 10000 attempts.
            Assert.That(resetEvent.WaitOne(TimeSpan.FromSeconds(10)), "The secondary lock user didn't finish 10000 iterations in less than 10 seconds. Probably dead locked!");
            runner.Shutdown();
        }
        private void StopMonitorThreads()
        {
            lock (monitor)
            {
                if (monitorStarted.CompareAndSet(true, false))
                {
                    AutoResetEvent shutdownEvent = new AutoResetEvent(false);

                    // Attempt to wait for the Timer to shutdown, but don't wait
                    // forever, if they don't shutdown after two seconds, just quit.
                    this.connectionCheckTimer.Dispose(shutdownEvent);
                    if (!shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(3000), false))
                    {
                        Tracer.WarnFormat("InactivityMonitor[{0}]: Timer Task didn't shutdown properly.", instanceId);
                    }

                    this.asyncTasks.RemoveTask(this.asyncWriteTask);
                    this.asyncTasks.RemoveTask(this.asyncErrorTask);

                    this.asyncTasks.Shutdown();
                    this.asyncTasks           = null;
                    this.asyncWriteTask       = null;
                    this.asyncErrorTask       = null;
                    this.connectionCheckTimer = null;
                }
            }

            Tracer.DebugFormat("InactivityMonitor[{0}]: Stopped Monitor Threads.", instanceId);
        }
        private void StartMonitorThreads()
        {
            lock (monitor)
            {
                if (monitorStarted.Value)
                {
                    return;
                }

                if (localWireFormatInfo == null)
                {
                    return;
                }

                if (remoteWireFormatInfo == null)
                {
                    return;
                }

                readCheckTime =
                    Math.Min(
                        localWireFormatInfo.MaxInactivityDuration,
                        remoteWireFormatInfo.MaxInactivityDuration);
                initialDelayTime =
                    Math.Min(
                        localWireFormatInfo.MaxInactivityDurationInitialDelay,
                        remoteWireFormatInfo.MaxInactivityDurationInitialDelay);

                this.asyncTasks = new CompositeTaskRunner();

                this.asyncErrorTask = new AsyncSignalReadErrorkTask(this, next.RemoteAddress);
                this.asyncWriteTask = new AsyncWriteTask(this);

                this.asyncTasks.AddTask(this.asyncErrorTask);
                this.asyncTasks.AddTask(this.asyncWriteTask);

                if (readCheckTime > 0)
                {
                    monitorStarted.Value = true;

                    writeCheckTime = readCheckTime > 3 ? readCheckTime / 3 : readCheckTime;

                    writeCheckTimer = new Timer(
                        new TimerCallback(WriteCheck),
                        null,
                        initialDelayTime,
                        writeCheckTime
                        );
                    readCheckTimer = new Timer(
                        new TimerCallback(ReadCheck),
                        null,
                        initialDelayTime,
                        readCheckTime
                        );
                }
            }
        }
Пример #6
0
        private void StopMonitorThreads()
        {
            lock (_monitor)
                if (_monitorStarted.CompareAndSet(true, false))
                {
                    _connectionCheckTimer.Dispose();

                    _connectionCheckTimer.Dispose();

                    _asyncTasks.Shutdown();
                    _asyncTasks     = null;
                    _asyncWriteTask = null;
                    _asyncErrorTask = null;
                }
        }
Пример #7
0
        private void StopMonitorThreads()
        {
            lock (monitor)
            {
                if (monitorStarted.CompareAndSet(true, false))
                {
                    // Attempt to wait for the Timer to shutdown, but don't wait
                    // forever, if they don't shutdown after two seconds, just quit.
                    ThreadUtil.DisposeTimer(connectionCheckTimer, 2000);

                    this.asyncTasks.Shutdown();
                    this.asyncTasks     = null;
                    this.asyncWriteTask = null;
                    this.asyncErrorTask = null;
                }
            }
        }
Пример #8
0
        private void StopMonitorThreads()
        {
            lock (monitor)
            {
                if (monitorStarted.CompareAndSet(true, false))
                {
                    AutoResetEvent shutdownEvent = new AutoResetEvent(false);

                    // Attempt to wait for the Timer to shutdown, but don't wait
                    // forever, if they don't shutdown after two seconds, just quit.
                    this.connectionCheckTimer.Dispose(shutdownEvent);
                    shutdownEvent.WaitOne(TimeSpan.FromMilliseconds(2000), false);

                    this.asyncTasks.Shutdown();
                    this.asyncTasks     = null;
                    this.asyncWriteTask = null;
                    this.asyncErrorTask = null;
                }
            }
        }
        public void ReadCheck()
        {
            DateTime            now        = DateTime.Now;
            TimeSpan            elapsed    = now - this.lastReadCheckTime;
            CompositeTaskRunner taskRunner = this.asyncTasks;

            if (!AllowReadCheck(elapsed))
            {
                Tracer.Debug("InactivityMonitor[" + instanceId + "]: A read check is not currently allowed.");
                return;
            }

            this.lastReadCheckTime = now;

            if (this.inRead.Value || this.failed.Value)
            {
                Tracer.DebugFormat("InactivityMonitor[{0}]: A receive is in progress or already failed.", instanceId);
                return;
            }

            if (!commandReceived.Value)
            {
                Tracer.DebugFormat("InactivityMonitor[{0}]: No message received since last read check! Sending an InactivityException!", instanceId);
                if (null != this.asyncErrorTask)
                {
                    this.asyncErrorTask.IsPending = true;
                }

                if (this.monitorStarted.Value && taskRunner != null)
                {
                    taskRunner.Wakeup();
                }
            }
            else
            {
                commandReceived.Value = false;
            }
        }
Пример #10
0
        private void StartMonitorThreads()
        {
            lock (monitor)
            {
                if (this.IsDisposed || this.disposing)
                {
                    return;
                }

                if (monitorStarted.Value)
                {
                    return;
                }

                if (localWireFormatInfo == null)
                {
                    return;
                }

                if (remoteWireFormatInfo == null)
                {
                    return;
                }

                readCheckTime =
                    Math.Min(
                        localWireFormatInfo.MaxInactivityDuration,
                        remoteWireFormatInfo.MaxInactivityDuration);
                initialDelayTime = remoteWireFormatInfo.MaxInactivityDurationInitialDelay > 0 ?
                                   Math.Min(localWireFormatInfo.MaxInactivityDurationInitialDelay,
                                            remoteWireFormatInfo.MaxInactivityDurationInitialDelay) :
                                   localWireFormatInfo.MaxInactivityDurationInitialDelay;

                if (readCheckTime > 0)
                {
                    Tracer.DebugFormat("InactivityMonitor[{0}]: Read Check time interval: {1}",
                                       instanceId, readCheckTime);
                    Tracer.DebugFormat("InactivityMonitor[{0}]: Initial Delay time interval: {1}",
                                       instanceId, initialDelayTime);

                    monitorStarted.Value = true;
                    this.asyncTasks      = new CompositeTaskRunner("InactivityMonitor[" + instanceId + "].Runner");

                    this.asyncErrorTask = new AsyncSignalReadErrorkTask(this, next.RemoteAddress);
                    this.asyncWriteTask = new AsyncWriteTask(this);

                    this.asyncTasks.AddTask(this.asyncErrorTask);
                    this.asyncTasks.AddTask(this.asyncWriteTask);

                    writeCheckTime = readCheckTime > 3 ? readCheckTime / 3 : readCheckTime;

                    Tracer.DebugFormat("InactivityMonitor[{0}]: Write Check time interval: {1}",
                                       instanceId, writeCheckTime);

                    this.connectionCheckTimer = new Timer(
                        new TimerCallback(CheckConnection),
                        null,
                        initialDelayTime,
                        writeCheckTime
                        );
                }
            }
        }
Пример #11
0
        private void StartMonitorThreads()
        {
            lock (monitor)
            {
                if (this.IsDisposed || this.disposing)
                {
                    return;
                }

                if (monitorStarted.Value)
                {
                    return;
                }

                if (localWireFormatInfo == null)
                {
                    return;
                }

                if (remoteWireFormatInfo == null)
                {
                    return;
                }

                if (localWireFormatInfo.MaxInactivityDuration != 0 &&
                    remoteWireFormatInfo.WriteCheckInterval != 0)
                {
                    readCheckTime =
                        Math.Max(
                            localWireFormatInfo.ReadCheckInterval,
                            remoteWireFormatInfo.WriteCheckInterval);

                    this.asyncErrorTask = new AsyncSignalReadErrorkTask(this, next.RemoteAddress);
                }

                if (localWireFormatInfo.MaxInactivityDuration != 0)
                {
                    if (remoteWireFormatInfo.Version > 1.0)
                    {
                        writeCheckTime =
                            Math.Max(localWireFormatInfo.WriteCheckInterval,
                                     remoteWireFormatInfo.ReadCheckInterval);
                    }
                    else
                    {
                        writeCheckTime = localWireFormatInfo.MaxInactivityDuration;
                    }

                    this.asyncWriteTask = new AsyncWriteTask(this);
                }

                initialDelayTime = localWireFormatInfo.MaxInactivityDurationInitialDelay > 0 ?
                                   localWireFormatInfo.MaxInactivityDurationInitialDelay : writeCheckTime;

                Tracer.DebugFormat("InactivityMonitor[{0}]: Read Check time interval: {1}",
                                   instanceId, readCheckTime);
                Tracer.DebugFormat("InactivityMonitor[{0}]: Initial Delay time interval: {1}",
                                   instanceId, initialDelayTime);

                this.asyncTasks = new CompositeTaskRunner();

                if (this.asyncErrorTask != null)
                {
                    Tracer.DebugFormat("InactivityMonitor[{0}]: Adding the Async Read Check Task to the Runner.", instanceId);
                    this.asyncTasks.AddTask(this.asyncErrorTask);
                }

                if (this.asyncWriteTask != null)
                {
                    Tracer.DebugFormat("InactivityMonitor[{0}]: Write Check time interval: {1}",
                                       instanceId, writeCheckTime);
                    this.asyncTasks.AddTask(this.asyncWriteTask);
                }

                if (this.asyncErrorTask != null || this.asyncWriteTask != null)
                {
                    Tracer.DebugFormat("InactivityMonitor[{0}]: Starting the Monitor Timer.", instanceId);
                    monitorStarted.Value = true;

                    this.connectionCheckTimer = new Timer(
                        new TimerCallback(CheckConnection),
                        null,
                        initialDelayTime,
                        writeCheckTime
                        );
                }
            }
        }
Пример #12
0
        private void StartMonitorThreads()
        {
            lock ( _monitor )
            {
                if (IsDisposed || _disposing)
                {
                    return;
                }

                if (_monitorStarted.Value)
                {
                    return;
                }

                if (_localWireFormatInfo == null)
                {
                    return;
                }

                if (_remoteWireFormatInfo == null)
                {
                    return;
                }

                if (_localWireFormatInfo.MaxInactivityDuration != 0 &&
                    _remoteWireFormatInfo.WriteCheckInterval != 0)
                {
                    ReadCheckTime =
                        Math.Max(
                            _localWireFormatInfo.ReadCheckInterval,
                            _remoteWireFormatInfo.WriteCheckInterval);

                    _asyncErrorTask = new AsyncSignalReadErrorkTask(this, Next.RemoteAddress);
                }

                if (_localWireFormatInfo.MaxInactivityDuration != 0)
                {
                    if (_remoteWireFormatInfo.Version > 1.0)
                    {
                        WriteCheckTime =
                            Math.Max(_localWireFormatInfo.WriteCheckInterval,
                                     _remoteWireFormatInfo.ReadCheckInterval);
                    }
                    else
                    {
                        WriteCheckTime = _localWireFormatInfo.WriteCheckInterval;
                    }

                    _asyncWriteTask = new AsyncWriteTask(this);
                }

                InitialDelayTime = _localWireFormatInfo.MaxInactivityDurationInitialDelay > 0
                    ? _localWireFormatInfo.MaxInactivityDurationInitialDelay
                    : WriteCheckTime;

                _asyncTasks = new CompositeTaskRunner();

                if (_asyncErrorTask != null)
                {
                    _asyncTasks.AddTask(_asyncErrorTask);
                }

                if (_asyncWriteTask != null)
                {
                    Tracer.WarnFormat("InactivityMonitor[{0}]: Write Check time interval: {1}",
                                      _instanceId,
                                      WriteCheckTime);
                    _asyncTasks.AddTask(_asyncWriteTask);
                }

                if (_asyncErrorTask == null && _asyncWriteTask == null)
                {
                    return;
                }

                Tracer.WarnFormat("InactivityMonitor[{0}]: Starting the Monitor Timer.", _instanceId);
                _monitorStarted.Value = true;

                _connectionCheckTimer = new Timer(
                    CheckConnection,
                    null,
                    InitialDelayTime,
                    WriteCheckTime
                    );
            }
        }