示例#1
0
        private void DispatchMany(ReceptionAssistant <TMessage> assistant)
        {
            assistant.IsStopPooling = true;

            Task.Run(() =>
            {
                try
                {
                    Parallel.ForEach(assistant.Pool, new ParallelOptions
                    {
                        CancellationToken = _cts.Token
                    }, DispatchMessage);
                }
                catch (OperationCanceledException)
                {
                }

                assistant.Pool.Clear();

                assistant.IsStopPooling = false;

                lock (assistant.PoolingLocker)
                {
                    Monitor.Pulse(assistant.PoolingLocker);
                }
            }, _cts.Token);
        }
示例#2
0
        private void RequeueProcessingMessages <TMessage>(ReceptionAssistant <TMessage> assistant)
        {
            var database = _connectionFactory.GetDatabase();
            var items    = database.ListRange(assistant.ProcessingQueueName);

            database.ListRightPush(assistant.QueueName, items);
            database.KeyDelete(assistant.ProcessingQueueName);
        }
示例#3
0
        private void RequeueProcessingMessages <TMessage>(ReceptionAssistant <TMessage> assistant)
        {
            var queue = GetQueue(assistant.QueueName);

            var queueProcessing = GetQueue(assistant.ProcessingQueueName);

            foreach (var item in queueProcessing)
            {
                queue.Insert(0, item);
            }

            queueProcessing.Clear();
        }
示例#4
0
        private void RemoveProcessingMessage <TMessage>(ReceptionAssistant <TMessage> assistant, IDatabase database, RedisValue rawMessage)
        {
            if (rawMessage == RedisValue.Null)
            {
                return;
            }

            try
            {
                database.ListRemove(assistant.ProcessingQueueName, rawMessage, 1);
                database.HashDelete(assistant.QueueName + HashQueuePostfix, rawMessage.GetString().RemoveEnqueueTime().GetMD5());
            }
            catch { }
        }
示例#5
0
        private void RemoveProcessingMessage <TMessage>(ReceptionAssistant <TMessage> assistant, List <string> queueProcessing, string rawMessage)
        {
            if (rawMessage == null)
            {
                return;
            }

            try
            {
                var hashSet = GetHashSet(assistant.QueueName);

                queueProcessing.Remove(rawMessage);
                hashSet.Remove(rawMessage.RemoveEnqueueTime().GetMD5());
            }
            catch { }
        }
示例#6
0
        private void StartDequeue()
        {
            DequeueTask = Task.Run(() =>
            {
                var assistant = new ReceptionAssistant <TMessage>(HostId, QueueName, _cts.Token);

                try
                {
                    var provider = QueueProviderFactory.CreateProvider(_provider);
                    provider.Dequeue <TMessage>(assistant, Pooling);
                }
                catch (Exception ex)
                {
                    LogFactory.GetLogger().Error(string.Format("Receive Task Error for queue \"{0}\".", assistant.QueueName), ex);
                }
            }, _cts.Token);

            ConsumerHealth.Register(this);
        }
示例#7
0
        public void Enqueue(string queueName, object message)
        {
            if (string.IsNullOrWhiteSpace(queueName) || message == null)
            {
                return;
            }

            var json  = message.Serialize();
            var queue = GetQueue(queueName);

            string           hash    = null;
            HashSet <string> hashSet = null;

            if (!IgnoreHash)
            {
                hash    = json.GetMD5();
                hashSet = GetHashSet(queueName);
                if (hashSet.Contains(hash))
                {
                    return;
                }
            }

            var hostId        = ConfigSource.GetAppSetting("DQueue.HostId");
            var dequeueLocker = ReceptionAssistant.GetLocker(queueName + string.Format(Constants.DequeueLockerFlag, hostId));

            lock (dequeueLocker)
            {
                queue.Add(json.AddEnqueueTime());

                if (!IgnoreHash)
                {
                    hashSet.Add(hash);
                }

                Monitor.Pulse(dequeueLocker);
            }
        }
示例#8
0
        public void Dequeue <TMessage>(ReceptionAssistant <TMessage> assistant, Action <ReceptionContext <TMessage> > handler)
        {
            if (assistant == null || string.IsNullOrWhiteSpace(assistant.QueueName) || handler == null)
            {
                return;
            }

            var receptionStatus = ReceptionStatus.None;

            RequeueProcessingMessages(assistant);

            assistant.Cancellation.Register(() =>
            {
                receptionStatus = ReceptionStatus.Withdraw;

                lock (assistant.DequeueLocker)
                {
                    Monitor.PulseAll(assistant.DequeueLocker);
                }

                RequeueProcessingMessages(assistant);
            });

            while (true)
            {
                if (receptionStatus == ReceptionStatus.Withdraw)
                {
                    break;
                }

                var message    = default(TMessage);
                var rawMessage = default(string);

                lock (assistant.DequeueLocker)
                {
                    var queue           = GetQueue(assistant.QueueName);
                    var queueProcessing = GetQueue(assistant.ProcessingQueueName);

                    if (queue.Count == 0)
                    {
                        Monitor.Wait(assistant.DequeueLocker);
                    }

                    try
                    {
                        rawMessage = queue[0];
                        queue.RemoveAt(0);
                        queueProcessing.Add(rawMessage);
                        message = rawMessage.Deserialize <TMessage>();
                    }
                    catch (Exception ex)
                    {
                        LogFactory.GetLogger().Error(string.Format("[AspNetProvider] Get Message Error! Raw Message: \"{0}\".", rawMessage), ex);
                        RemoveProcessingMessage(assistant, queueProcessing, rawMessage);
                    }
                }

                if (message != null)
                {
                    handler(new ReceptionContext <TMessage>(message, rawMessage, assistant, HandlerCallback));
                }
            }
        }
示例#9
0
        public void Dequeue <TMessage>(ReceptionAssistant <TMessage> assistant, Action <ReceptionContext <TMessage> > handler)
        {
            if (assistant == null || string.IsNullOrWhiteSpace(assistant.QueueName) || handler == null)
            {
                return;
            }

            using (var connection = _connectionFactory.CreateConnection())
            {
                using (var model = connection.CreateModel())
                {
                    model.QueueDeclare(assistant.QueueName, false, false, false, null);
                    var consumer = new QueueingBasicConsumer(model);
                    model.BasicConsume(assistant.QueueName, false, consumer);

                    var receptionStatus = ReceptionStatus.None;

                    assistant.Cancellation.Register(() =>
                    {
                        receptionStatus = ReceptionStatus.Withdraw;
                        model.BasicCancel(consumer.ConsumerTag);
                    });

                    while (true)
                    {
                        if (receptionStatus == ReceptionStatus.Withdraw)
                        {
                            break;
                        }

                        var eventArg = consumer.Queue.Dequeue();

                        if (receptionStatus == ReceptionStatus.Withdraw)
                        {
                            break;
                        }

                        var message = default(TMessage);

                        if (eventArg != null)
                        {
                            var json = Encoding.UTF8.GetString(eventArg.Body);
                            message = json.Deserialize <TMessage>();
                        }

                        if (message != null)
                        {
                            handler(new ReceptionContext <TMessage>(message, null, assistant, (sender, status) =>
                            {
                                if (status == ReceptionStatus.Completed)
                                {
                                    model.BasicAck(eventArg.DeliveryTag, false);
                                }
                                else if (status == ReceptionStatus.Retry)
                                {
                                    throw new NotImplementedException();
                                }
                            }));
                        }
                    }
                }
            }
        }
示例#10
0
        public void Dequeue <TMessage>(ReceptionAssistant <TMessage> assistant, Action <ReceptionContext <TMessage> > handler)
        {
            if (assistant == null || string.IsNullOrWhiteSpace(assistant.QueueName) || handler == null)
            {
                return;
            }

            var receptionStatus = ReceptionStatus.None;

            _connectionFactory.GetSubscriber().Subscribe(assistant.QueueName + SubscriberKey, (channel, val) =>
            {
                if (val == SubscriberValue)
                {
                    lock (assistant.DequeueLocker)
                    {
                        Monitor.Pulse(assistant.DequeueLocker);
                    }
                }
            });

            RequeueProcessingMessages(assistant);

            assistant.Cancellation.Register(() =>
            {
                _connectionFactory.GetSubscriber().Unsubscribe(assistant.QueueName + SubscriberKey);

                receptionStatus = ReceptionStatus.Withdraw;

                lock (assistant.DequeueLocker)
                {
                    Monitor.PulseAll(assistant.DequeueLocker);
                }

                RequeueProcessingMessages(assistant);
            });

            while (true)
            {
                if (receptionStatus == ReceptionStatus.Withdraw)
                {
                    break;
                }

                var message    = default(TMessage);
                var rawMessage = RedisValue.Null;

                lock (assistant.DequeueLocker)
                {
                    var database = _connectionFactory.GetDatabase();
                    if (database.ListLength(assistant.QueueName) == 0)
                    {
                        Monitor.Wait(assistant.DequeueLocker);
                    }

                    try
                    {
                        rawMessage = database.ListRightPopLeftPush(assistant.QueueName, assistant.ProcessingQueueName);
                        message    = rawMessage.GetString().Deserialize <TMessage>();
                    }
                    catch (Exception ex)
                    {
                        LogFactory.GetLogger().Error(string.Format("[RedisProvider] Get Message Error! Raw Message: \"{0}\".", rawMessage), ex);
                        RemoveProcessingMessage(assistant, database, rawMessage);
                    }
                }

                if (message != null)
                {
                    handler(new ReceptionContext <TMessage>(message, rawMessage, assistant, HandlerCallback));
                }
            }
        }