示例#1
0
        public void PostTimeoutAfter(
            ICorrelatedMessage source,
            Guid targetId,
            long timeoutMs,
            Action <TimeoutMessage> timeoutAction)
        {
            Ensure.NotNull(timeoutAction, "timeoutAction");
            var timeoutRequest = new TimeoutRequestNode(
                source,
                targetId,
                timeoutMs,
                timeoutAction);

            lock (_queueLock)
            {
                if (_queue.Count >= _queue.MaxSize)
                {
                    _queue.Resize(_queue.MaxSize + 100);
                }
                _queue.Enqueue(timeoutRequest, timeoutMs);
            }
            if (_starving)
            {
                _msgAddEvent.Set();
            }
        }
示例#2
0
        private void ReadFromQueue(object o)
        {
            Thread.BeginThreadAffinity(); // ensure we are not switching between OS threads. Required at least for v8.

            while (!_stop)
            {
                TimeoutRequestNode msg = null;
                try
                {
                    var epochMs = EpochMsFromDateTime(DateTime.UtcNow);
                    lock (_queueLock)
                        _queue.TryPeek(out msg);
                    if (msg == null)
                    {
                        _starving = true;
                        _msgAddEvent.Wait(100);
                        _msgAddEvent.Reset();
                        _starving = false;
                    }
                    else if (msg.TimeoutMs > epochMs)
                    {
                        _starving = true;
                        _msgAddEvent.Wait((int)(msg.TimeoutMs - epochMs));
                        _msgAddEvent.Reset();
                        _starving = false;
                    }
                    else       // epochMs >= msg.TimeoutMs
                    {
                        lock (_queueLock)
                            _queue.TryDequeue(out msg);
                        var overdueMs = (epochMs - msg.TimeoutMs);
                        if (overdueMs > 100)
                        {
                            if (Log.LogLevel >= LogLevel.Info)
                            {
                                Log.Info("Message should have timed out at " + msg.TimeoutMs + ", but it's now " + epochMs + " which is " + overdueMs + " late");
                            }
                        }
                        msg.SendTimeout();
                    }
                }
                catch (Exception ex)
                {
                    Log.ErrorException(ex, $"Error while processing message {msg} in queued handler TimeoutService.");
                }
            }
            _stopped.Set();
            Thread.EndThreadAffinity();
        }