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); }
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); }
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(); }
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 { } }
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 { } }
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); }
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); } }
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)); } } }
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(); } })); } } } } }
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)); } } }