public void TestDequeue() { FifoMessageDispatchChannel channel = new FifoMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); MessageDispatch dispatch3 = new MessageDispatch(); channel.Start(); Assert.IsTrue( channel.Running == true ); DateTime timeStarted = DateTime.Now; Assert.IsTrue( channel.Dequeue(TimeSpan.FromMilliseconds(1000)) == null ); DateTime timeFinished = DateTime.Now; TimeSpan elapsed = timeFinished - timeStarted; Assert.IsTrue( elapsed.TotalMilliseconds >= 999 ); channel.Enqueue( dispatch1 ); channel.Enqueue( dispatch2 ); channel.Enqueue( dispatch3 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 3 ); Assert.IsTrue( channel.Dequeue( TimeSpan.FromMilliseconds(Timeout.Infinite) ) == dispatch1 ); Assert.IsTrue( channel.Dequeue( TimeSpan.Zero ) == dispatch2 ); Assert.IsTrue( channel.Dequeue( TimeSpan.FromMilliseconds(1000) ) == dispatch3 ); Assert.IsTrue( channel.Count == 0 ); Assert.IsTrue( channel.Empty == true ); }
public MessageAck(MessageDispatch dispatch, byte ackType, int messageCount) : base() { this.ackType = ackType; this.consumerId = dispatch.ConsumerId; this.destination = dispatch.Destination; this.lastMessageId = dispatch.Message.MessageId; this.messageCount = messageCount; }
public void TestDequeue() { SimplePriorityMessageDispatchChannel channel = new SimplePriorityMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); MessageDispatch dispatch3 = new MessageDispatch(); Message message1 = new Message(); Message message2 = new Message(); Message message3 = new Message(); message1.Priority = 1; message2.Priority = 2; message3.Priority = 3; dispatch1.Message = message1; dispatch2.Message = message2; dispatch3.Message = message3; channel.Start(); Assert.IsTrue( channel.Running == true ); DateTime timeStarted = DateTime.Now; Assert.IsTrue( channel.Dequeue(TimeSpan.FromMilliseconds(1000)) == null ); DateTime timeFinished = DateTime.Now; TimeSpan elapsed = timeFinished - timeStarted; Assert.IsTrue( elapsed.TotalMilliseconds >= 999 ); channel.Enqueue( dispatch1 ); channel.Enqueue( dispatch2 ); channel.Enqueue( dispatch3 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 3 ); Assert.IsTrue( channel.Dequeue( TimeSpan.FromMilliseconds(Timeout.Infinite) ) == dispatch3 ); Assert.IsTrue( channel.Dequeue( TimeSpan.Zero ) == dispatch2 ); Assert.IsTrue( channel.Dequeue( TimeSpan.FromMilliseconds(1000) ) == dispatch1 ); Assert.IsTrue( channel.Count == 0 ); Assert.IsTrue( channel.Empty == true ); }
public void TestEnqueue() { FifoMessageDispatchChannel channel = new FifoMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); Assert.IsTrue( channel.Empty == true ); Assert.IsTrue( channel.Count == 0 ); channel.Enqueue( dispatch1 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 1 ); channel.Enqueue( dispatch2 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 2 ); }
public virtual bool Equals(MessageDispatch that) { if (!Equals(this.ConsumerId, that.ConsumerId)) { return(false); } if (!Equals(this.Destination, that.Destination)) { return(false); } if (!Equals(this.Message, that.Message)) { return(false); } if (!Equals(this.RedeliveryCounter, that.RedeliveryCounter)) { return(false); } return(true); }
public void Dispatch(MessageDispatch messageDispatch) { // Auto ack messages when we reach 75% of the prefetch deliveredCounter++; if(deliveredCounter > (0.75 * this.info.PrefetchSize)) { try { MessageAck ack = new MessageAck(); ack.AckType = (byte)AckType.ConsumedAck; ack.ConsumerId = messageDispatch.ConsumerId; ack.Destination = messageDispatch.Destination; ack.FirstMessageId = messageDispatch.Message.MessageId; ack.MessageCount = deliveredCounter; this.connection.Oneway(ack); this.deliveredCounter = 0; } catch(Exception e) { this.connection.OnAsyncException(e); } } DestinationInfo destInfo = messageDispatch.Message.DataStructure as DestinationInfo; if(destInfo != null) { ProcessDestinationInfo(destInfo); } else { // This can happen across networks Tracer.Debug("Unexpected message was dispatched to the AdvisoryConsumer: " + messageDispatch); } }
public void TestDequeueNoWait() { FifoMessageDispatchChannel channel = new FifoMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); MessageDispatch dispatch3 = new MessageDispatch(); Assert.IsTrue( channel.Running == false ); Assert.IsTrue( channel.DequeueNoWait() == null ); channel.Enqueue( dispatch1 ); channel.Enqueue( dispatch2 ); channel.Enqueue( dispatch3 ); Assert.IsTrue( channel.DequeueNoWait() == null ); channel.Start(); Assert.IsTrue( channel.Running == true ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 3 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch1 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch2 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch3 ); Assert.IsTrue( channel.Count == 0 ); Assert.IsTrue( channel.Empty == true ); }
public void ExecuteFirst(MessageDispatch dispatch) { // Add the data to the queue. this.messageQueue.EnqueueFirst(dispatch); this.Wakeup(); }
public void Dispatch(MessageDispatch dispatch) { try { MessageConsumer consumer = null; lock(this.consumers.SyncRoot) { if(this.consumers.Contains(dispatch.ConsumerId)) { consumer = this.consumers[dispatch.ConsumerId] as MessageConsumer; } } // If the consumer is not available, just ignore the message. // Otherwise, dispatch the message to the consumer. if(consumer != null) { consumer.Dispatch(dispatch); } } catch(Exception ex) { Tracer.DebugFormat("Caught Exception While Dispatching: {0}", ex.Message ); } }
public virtual Response processMessageDispatch(MessageDispatch dispatch) { return null; }
public void BeforeMessageIsConsumed(MessageDispatch dispatch) { this.lastDeliveredSequenceId = dispatch.Message.MessageId.BrokerSequenceId; if(!IsAutoAcknowledgeBatch) { lock(this.dispatchedMessages) { this.dispatchedMessages.AddFirst(dispatch); } if(this.session.IsTransacted) { this.AckLater(dispatch, AckType.DeliveredAck); } } }
public MessageDispatch[] RemoveAll() { MessageDispatch[] result; lock(mutex) { result = new MessageDispatch[this.Count]; channel.CopyTo(result, 0); channel.Clear(); } return result; }
public void BeforeMessageIsConsumed(MessageDispatch dispatch) { this.lastDeliveredSequenceId = dispatch.Message.MessageId.BrokerSequenceId; if(!IsAutoAcknowledgeBatch) { if (this.session.IsTransacted) { this.session.TransactionContext.SyncRoot.WaitOne(); // In the case where the consumer is operating in concert with a // distributed TX manager we need to wait whenever the TX is being // controlled by the DTC as it completes all operations async and // we cannot start consumption again until all its tasks have completed.) if (this.session.TransactionContext.InNetTransaction && this.session.TransactionContext.NetTxState == TransactionContext.TxState.Pending) { this.session.TransactionContext.SyncRoot.ReleaseMutex(); this.session.TransactionContext.DtcWaitHandle.WaitOne(); } else { this.session.TransactionContext.SyncRoot.ReleaseMutex(); } } lock(this.dispatchedMessages) { this.dispatchedMessages.AddFirst(dispatch); } if(this.session.IsTransacted) { //this.session.TransactionContext.DtcWaitHandle.WaitOne(); this.AckLater(dispatch, AckType.DeliveredAck); } } }
public void TestPeek() { SimplePriorityMessageDispatchChannel channel = new SimplePriorityMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); Message message1 = new Message(); Message message2 = new Message(); message1.Priority = 2; message2.Priority = 1; dispatch1.Message = message1; dispatch2.Message = message2; Assert.IsTrue( channel.Empty == true ); Assert.IsTrue( channel.Count == 0 ); channel.EnqueueFirst( dispatch1 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 1 ); channel.EnqueueFirst( dispatch2 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 2 ); Assert.IsTrue( channel.Peek() == null ); channel.Start(); Assert.IsTrue( channel.Peek() == dispatch1 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch1 ); Assert.IsTrue( channel.Peek() == dispatch2 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch2 ); }
private ActiveMQMessage CreateActiveMQMessage(MessageDispatch dispatch) { ActiveMQMessage message = dispatch.Message.Clone() as ActiveMQMessage; if(this.ConsumerTransformer != null) { IMessage newMessage = ConsumerTransformer(this.session, this, message); if(newMessage != null) { message = this.messageTransformation.TransformMessage<ActiveMQMessage>(newMessage); } } message.Connection = this.session.Connection; if(IsClientAcknowledge) { message.Acknowledger += new AcknowledgeHandler(DoClientAcknowledge); } else if(IsIndividualAcknowledge) { message.Acknowledger += new AcknowledgeHandler(DoIndividualAcknowledge); } else { message.Acknowledger += new AcknowledgeHandler(DoNothingAcknowledge); } return message; }
public override void Dispatch(MessageDispatch md) { if(md.Message == null) { Tracer.Debug("QueueBrowser recieved Null Message in Dispatch, Browse Done."); parent.browseDone.Value = true; } else { Tracer.Debug("QueueBrowser dispatching next Message to Consumer."); base.Dispatch(md); } parent.NotifyMessageAvailable(); }
public void Dispatch(MessageDispatch dispatch) { if(this.executor != null) { this.executor.Execute(dispatch); } }
private void AckLater(MessageDispatch dispatch, AckType type) { // Don't acknowledge now, but we may need to let the broker know the // consumer got the message to expand the pre-fetch window if(this.session.IsTransacted) { this.session.DoStartTransaction(); if(!synchronizationRegistered) { Tracer.DebugFormat("Consumer {0} Registering new MessageConsumerSynchronization", this.info.ConsumerId); this.synchronizationRegistered = true; this.session.TransactionContext.AddSynchronization(new MessageConsumerSynchronization(this)); } } this.deliveredCounter++; MessageAck oldPendingAck = pendingAck; pendingAck = new MessageAck(); pendingAck.AckType = (byte) type; pendingAck.ConsumerId = this.info.ConsumerId; pendingAck.Destination = dispatch.Destination; pendingAck.LastMessageId = dispatch.Message.MessageId; pendingAck.MessageCount = deliveredCounter; if(this.session.IsTransacted && this.session.TransactionContext.InTransaction) { pendingAck.TransactionId = this.session.TransactionContext.TransactionId; } if(oldPendingAck == null) { pendingAck.FirstMessageId = pendingAck.LastMessageId; } else if(oldPendingAck.AckType == pendingAck.AckType) { pendingAck.FirstMessageId = oldPendingAck.FirstMessageId; } else { // old pending ack being superseded by ack of another type, if is is not a delivered // ack and hence important, send it now so it is not lost. if(oldPendingAck.AckType != (byte) AckType.DeliveredAck) { if(Tracer.IsDebugEnabled) { Tracer.Debug("Sending old pending ack " + oldPendingAck + ", new pending: " + pendingAck); } this.session.Connection.Oneway(oldPendingAck); } else { if(Tracer.IsDebugEnabled) { Tracer.Debug("dropping old pending ack " + oldPendingAck + ", new pending: " + pendingAck); } } } if((0.5 * this.info.PrefetchSize) <= (this.deliveredCounter - this.additionalWindowSize)) { this.session.Connection.Oneway(pendingAck); this.pendingAck = null; this.deliveredCounter = 0; this.additionalWindowSize = 0; } }
public void AfterMessageIsConsumed(MessageDispatch dispatch, bool expired) { if(this.unconsumedMessages.Closed) { return; } if(expired) { lock(this.dispatchedMessages) { this.dispatchedMessages.Remove(dispatch); } AckLater(dispatch, AckType.DeliveredAck); } else { if(this.session.IsTransacted) { // Do nothing. } else if(this.IsAutoAcknowledgeEach) { if(this.deliveringAcks.CompareAndSet(false, true)) { lock(this.dispatchedMessages) { if(this.dispatchedMessages.Count != 0) { MessageAck ack = MakeAckForAllDeliveredMessages(AckType.ConsumedAck); if(ack != null) { this.dispatchedMessages.Clear(); this.session.SendAck(ack); } } } this.deliveringAcks.Value = false; } } else if(this.IsAutoAcknowledgeBatch) { AckLater(dispatch, AckType.ConsumedAck); } else if(IsClientAcknowledge || IsIndividualAcknowledge) { bool messageAckedByConsumer = false; lock(this.dispatchedMessages) { messageAckedByConsumer = this.dispatchedMessages.Contains(dispatch); } if(messageAckedByConsumer) { AckLater(dispatch, AckType.DeliveredAck); } } else { throw new NMSException("Invalid session state."); } } }
public void TestRemoveAll() { FifoMessageDispatchChannel channel = new FifoMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); MessageDispatch dispatch3 = new MessageDispatch(); channel.Enqueue( dispatch1 ); channel.Enqueue( dispatch2 ); channel.Enqueue( dispatch3 ); channel.Start(); Assert.IsTrue( channel.Running == true ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 3 ); Assert.IsTrue( channel.RemoveAll().Length == 3 ); Assert.IsTrue( channel.Count == 0 ); Assert.IsTrue( channel.Empty == true ); }
public void EnqueueFirst(MessageDispatch dispatch) { lock(this.mutex) { GetList(dispatch).AddFirst(dispatch); this.size++; Monitor.Pulse(this.mutex); } }
public virtual void Dispatch(MessageDispatch dispatch) { MessageListener listener = this.listener; bool dispatchMessage = false; try { lock(this.unconsumedMessages.SyncRoot) { if(this.clearDispatchList) { // we are reconnecting so lets flush the in progress messages this.clearDispatchList = false; this.unconsumedMessages.Clear(); if(this.pendingAck != null && this.pendingAck.AckType == (byte) AckType.DeliveredAck) { // on resumption a pending delivered ack will be out of sync with // re-deliveries. if(Tracer.IsDebugEnabled) { Tracer.Debug("removing pending delivered ack on transport interupt: " + pendingAck); } this.pendingAck = null; } } if(!this.unconsumedMessages.Closed) { if(listener != null && this.unconsumedMessages.Running) { dispatchMessage = true; } else { this.unconsumedMessages.Enqueue(dispatch); } } } if(dispatchMessage) { ActiveMQMessage message = CreateActiveMQMessage(dispatch); this.BeforeMessageIsConsumed(dispatch); try { bool expired = (!IgnoreExpiration && message.IsExpired()); if(!expired) { listener(message); } this.AfterMessageIsConsumed(dispatch, expired); } catch(Exception e) { if(IsAutoAcknowledgeBatch || IsAutoAcknowledgeEach || IsIndividualAcknowledge) { // Redeliver the message Rollback(); } else { // Transacted or Client ack: Deliver the next message. this.AfterMessageIsConsumed(dispatch, false); } Tracer.Error(this.info.ConsumerId + " Exception while processing message: " + e); // If aborted we stop the abort here and let normal processing resume. // This allows the session to shutdown normally and ack all messages // that have outstanding acks in this consumer. if((Thread.CurrentThread.ThreadState & ThreadState.AbortRequested) == ThreadState.AbortRequested) { Thread.ResetAbort(); } } } if(++dispatchedCount % 1000 == 0) { dispatchedCount = 0; Thread.Sleep(1); } } catch(Exception e) { this.session.Connection.OnSessionException(this.session, e); } }
public void TestEnqueueFront() { SimplePriorityMessageDispatchChannel channel = new SimplePriorityMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); channel.Start(); Assert.IsTrue( channel.Empty == true ); Assert.IsTrue( channel.Count == 0 ); channel.EnqueueFirst( dispatch1 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 1 ); channel.EnqueueFirst( dispatch2 ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 2 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch2 ); Assert.IsTrue( channel.DequeueNoWait() == dispatch1 ); }
public MessageDispatch[] RemoveAll() { MessageDispatch[] result; lock(mutex) { result = new MessageDispatch[this.size]; int copyPos = 0; for(int i = MAX_PRIORITY - 1; i >= 0; i--) { LinkedList<MessageDispatch> list = channels[i]; list.CopyTo(result, copyPos); copyPos += list.Count; size -= list.Count; list.Clear(); } } return result; }
public void TestRemoveAll() { SimplePriorityMessageDispatchChannel channel = new SimplePriorityMessageDispatchChannel(); MessageDispatch dispatch1 = new MessageDispatch(); MessageDispatch dispatch2 = new MessageDispatch(); MessageDispatch dispatch3 = new MessageDispatch(); Message message1 = new Message(); Message message2 = new Message(); Message message3 = new Message(); message1.Priority = 1; message2.Priority = 2; message3.Priority = 3; dispatch1.Message = message1; dispatch2.Message = message2; dispatch3.Message = message3; channel.Enqueue( dispatch1 ); channel.Enqueue( dispatch2 ); channel.Enqueue( dispatch3 ); channel.Start(); Assert.IsTrue( channel.Running == true ); Assert.IsTrue( channel.Empty == false ); Assert.IsTrue( channel.Count == 3 ); Assert.IsTrue( channel.RemoveAll().Length == 3 ); Assert.IsTrue( channel.Count == 0 ); Assert.IsTrue( channel.Empty == true ); }
protected LinkedList<MessageDispatch> GetList(MessageDispatch md) { return channels[GetPriority(md)]; }
public void EnqueueFirst(MessageDispatch dispatch) { lock(this.mutex) { this.channel.AddFirst(dispatch); Monitor.Pulse(this.mutex); } }
protected int GetPriority(MessageDispatch message) { int priority = (int) MsgPriority.Lowest; if(message.Message != null) { priority = Math.Max((int) message.Message.Priority, 0); priority = Math.Min(priority, 9); } return priority; }
protected void DispatchMessage(MessageDispatch dispatch) { lock(dispatchers.SyncRoot) { if(dispatchers.Contains(dispatch.ConsumerId)) { IDispatcher dispatcher = (IDispatcher) dispatchers[dispatch.ConsumerId]; // Can be null when a consumer has sent a MessagePull and there was // no available message at the broker to dispatch or when signalled // that the end of a Queue browse has been reached. if(dispatch.Message != null) { dispatch.Message.ReadOnlyBody = true; dispatch.Message.ReadOnlyProperties = true; dispatch.Message.RedeliveryCounter = dispatch.RedeliveryCounter; } dispatcher.Dispatch(dispatch); return; } } Tracer.Error("No such consumer active: " + dispatch.ConsumerId); }
public virtual bool Equals(MessageDispatch that) { if(!Equals(this.ConsumerId, that.ConsumerId)) { return false; } if(!Equals(this.Destination, that.Destination)) { return false; } if(!Equals(this.Message, that.Message)) { return false; } if(!Equals(this.RedeliveryCounter, that.RedeliveryCounter)) { return false; } return true; }