Author: tabish
Date: Thu Nov 11 16:43:57 2010
New Revision: 1033989
URL: http://svn.apache.org/viewvc?rev=1033989&view=rev
Log:
Don't allow resources to be added when the parent is closing.
Use the shortcut Command isXXX methods in Connection.
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Connection.cs
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Session.cs
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Connection.cs
URL:
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Connection.cs?rev=1033989&r1=1033988&r2=1033989&view=diff
==============================================================================
---
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Connection.cs
(original)
+++
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Connection.cs
Thu Nov 11 16:43:57 2010
@@ -471,22 +471,34 @@ namespace Apache.NMS.ActiveMQ
internal void addDispatcher( ConsumerId id, IDispatcher dispatcher )
{
- this.dispatchers.Add( id, dispatcher );
+ if(!this.closing)
+ {
+ this.dispatchers.Add( id, dispatcher );
+ }
}
internal void removeDispatcher( ConsumerId id )
{
- this.dispatchers.Remove( id );
+ if(!this.closing)
+ {
+ this.dispatchers.Remove( id );
+ }
}
internal void addProducer( ProducerId id, MessageProducer producer )
{
- this.producers.Add( id, producer );
+ if(!this.closing)
+ {
+ this.producers.Add( id, producer );
+ }
}
internal void removeProducer( ProducerId id )
{
- this.producers.Remove( id );
+ if(!this.closing)
+ {
+ this.producers.Remove( id );
+ }
}
public void Close()
@@ -685,32 +697,32 @@ namespace Apache.NMS.ActiveMQ
/// <param name="command">A Command</param>
protected void OnCommand(ITransport commandTransport, Command command)
{
- if(command is MessageDispatch)
+ if(command.IsMessageDispatch)
{
WaitForTransportInterruptionProcessingToComplete();
DispatchMessage((MessageDispatch) command);
}
- else if(command is KeepAliveInfo)
+ else if(command.IsKeepAliveInfo)
{
OnKeepAliveCommand(commandTransport, (KeepAliveInfo) command);
}
- else if(command is WireFormatInfo)
+ else if(command.IsWireFormatInfo)
{
this.brokerWireFormatInfo = (WireFormatInfo) command;
}
- else if(command is BrokerInfo)
+ else if(command.IsBrokerInfo)
{
this.brokerInfo = (BrokerInfo) command;
this.brokerInfoReceived.countDown();
}
- else if(command is ShutdownInfo)
+ else if(command.IsShutdownInfo)
{
if(!closing && !closed)
{
OnException(commandTransport, new NMSException("Broker
closed this connection."));
}
}
- else if(command is ProducerAck)
+ else if(command.IsProducerAck)
{
ProducerAck ack = (ProducerAck) command as ProducerAck;
if(ack.ProducerId != null)
@@ -727,7 +739,7 @@ namespace Apache.NMS.ActiveMQ
}
}
}
- else if(command is ConnectionError)
+ else if(command.IsConnectionError)
{
if(!closing && !closed)
{
@@ -904,18 +916,18 @@ namespace Apache.NMS.ActiveMQ
public ActiveMQTempDestination CreateTemporaryDestination(bool topic)
{
- ActiveMQTempDestination destination = null;
+ ActiveMQTempDestination destination = null;
- if(topic)
- {
- destination = new ActiveMQTempTopic(
- info.ConnectionId.Value + ":" + Interlocked.Increment(ref
temporaryDestinationCounter));
- }
- else
- {
- destination = new ActiveMQTempQueue(
- info.ConnectionId.Value + ":" + Interlocked.Increment(ref
temporaryDestinationCounter));
- }
+ if(topic)
+ {
+ destination = new ActiveMQTempTopic(
+ info.ConnectionId.Value + ":" + Interlocked.Increment(ref
temporaryDestinationCounter));
+ }
+ else
+ {
+ destination = new ActiveMQTempQueue(
+ info.ConnectionId.Value + ":" + Interlocked.Increment(ref
temporaryDestinationCounter));
+ }
DestinationInfo command = new DestinationInfo();
command.ConnectionId = ConnectionId;
Modified:
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Session.cs
URL:
http://svn.apache.org/viewvc/activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Session.cs?rev=1033989&r1=1033988&r2=1033989&view=diff
==============================================================================
---
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Session.cs
(original)
+++
activemq/activemq-dotnet/Apache.NMS.ActiveMQ/trunk/src/main/csharp/Session.cs
Thu Nov 11 16:43:57 2010
@@ -25,53 +25,53 @@ using Apache.NMS.ActiveMQ.Util;
namespace Apache.NMS.ActiveMQ
{
- /// <summary>
- /// Default provider of ISession
- /// </summary>
- public class Session : ISession, IDispatcher
- {
- /// <summary>
- /// Private object used for synchronization, instead of public
"this"
- /// </summary>
- private readonly object myLock = new object();
-
- private readonly IDictionary consumers =
Hashtable.Synchronized(new Hashtable());
- private readonly IDictionary producers =
Hashtable.Synchronized(new Hashtable());
-
- private readonly SessionExecutor executor;
- private readonly TransactionContext transactionContext;
-
- private Connection connection;
-
- private bool dispatchAsync;
- private bool exclusive;
- private bool retroactive;
- private byte priority = 0;
-
- private readonly SessionInfo info;
- private int consumerCounter;
- private int producerCounter;
- private long nextDeliveryId;
- private long lastDeliveredSequenceId;
- private bool disposed = false;
- private bool closed = false;
- private bool closing = false;
- private TimeSpan disposeStopTimeout =
TimeSpan.FromMilliseconds(30000);
- private TimeSpan closeStopTimeout =
TimeSpan.FromMilliseconds(Timeout.Infinite);
- private TimeSpan requestTimeout;
- private readonly AcknowledgementMode acknowledgementMode;
+ /// <summary>
+ /// Default provider of ISession
+ /// </summary>
+ public class Session : ISession, IDispatcher
+ {
+ /// <summary>
+ /// Private object used for synchronization, instead of public "this"
+ /// </summary>
+ private readonly object myLock = new object();
+
+ private readonly IDictionary consumers = Hashtable.Synchronized(new
Hashtable());
+ private readonly IDictionary producers = Hashtable.Synchronized(new
Hashtable());
+
+ private readonly SessionExecutor executor;
+ private readonly TransactionContext transactionContext;
+
+ private Connection connection;
+
+ private bool dispatchAsync;
+ private bool exclusive;
+ private bool retroactive;
+ private byte priority = 0;
+
+ private readonly SessionInfo info;
+ private int consumerCounter;
+ private int producerCounter;
+ private long nextDeliveryId;
+ private long lastDeliveredSequenceId;
+ private bool disposed = false;
+ private bool closed = false;
+ private bool closing = false;
+ private TimeSpan disposeStopTimeout = TimeSpan.FromMilliseconds(30000);
+ private TimeSpan closeStopTimeout =
TimeSpan.FromMilliseconds(Timeout.Infinite);
+ private TimeSpan requestTimeout;
+ private readonly AcknowledgementMode acknowledgementMode;
- public Session(Connection connection, SessionId sessionId,
AcknowledgementMode acknowledgementMode)
- {
+ public Session(Connection connection, SessionId sessionId,
AcknowledgementMode acknowledgementMode)
+ {
this.info = new SessionInfo();
this.info.SessionId = sessionId;
- this.connection = connection;
+ this.connection = connection;
this.connection.Oneway(this.info);
- this.acknowledgementMode = acknowledgementMode;
- this.requestTimeout = connection.RequestTimeout;
- this.dispatchAsync = connection.DispatchAsync;
- this.transactionContext = new TransactionContext(this);
+ this.acknowledgementMode = acknowledgementMode;
+ this.requestTimeout = connection.RequestTimeout;
+ this.dispatchAsync = connection.DispatchAsync;
+ this.transactionContext = new TransactionContext(this);
Uri brokerUri = connection.BrokerUri;
@@ -87,7 +87,7 @@ namespace Apache.NMS.ActiveMQ
this.ConsumerTransformer = connection.ConsumerTransformer;
this.ProducerTransformer = connection.ProducerTransformer;
- this.executor = new SessionExecutor(this,
this.consumers);
+ this.executor = new SessionExecutor(this, this.consumers);
if(connection.IsStarted)
{
@@ -95,296 +95,296 @@ namespace Apache.NMS.ActiveMQ
}
connection.AddSession(this);
- }
+ }
+
+ ~Session()
+ {
+ Dispose(false);
+ }
+
+ #region Property Accessors
+
+ /// <summary>
+ /// Sets the prefetch size, the maximum number of messages a broker
will dispatch to consumers
+ /// until acknowledgements are received.
+ /// </summary>
+ public int PrefetchSize
+ {
+ set{ this.connection.PrefetchPolicy.SetAll(value); }
+ }
+
+ /// <summary>
+ /// Sets the maximum number of messages to keep around per consumer
+ /// in addition to the prefetch window for non-durable topics until
messages
+ /// will start to be evicted for slow consumers.
+ /// Must be > 0 to enable this feature
+ /// </summary>
+ public int MaximumPendingMessageLimit
+ {
+ set{ this.connection.PrefetchPolicy.MaximumPendingMessageLimit =
value; }
+ }
+
+ /// <summary>
+ /// Enables or disables whether asynchronous dispatch should be used
by the broker
+ /// </summary>
+ public bool DispatchAsync
+ {
+ get{ return this.dispatchAsync; }
+ set{ this.dispatchAsync = value; }
+ }
+
+ /// <summary>
+ /// Enables or disables exclusive consumers when using queues. An
exclusive consumer means
+ /// only one instance of a consumer is allowed to process messages on
a queue to preserve order
+ /// </summary>
+ public bool Exclusive
+ {
+ get{ return this.exclusive; }
+ set{ this.exclusive = value; }
+ }
+
+ /// <summary>
+ /// Enables or disables retroactive mode for consumers; i.e. do they
go back in time or not?
+ /// </summary>
+ public bool Retroactive
+ {
+ get{ return this.retroactive; }
+ set{ this.retroactive = value; }
+ }
+
+ /// <summary>
+ /// Sets the default consumer priority for consumers
+ /// </summary>
+ public byte Priority
+ {
+ get{ return this.priority; }
+ set{ this.priority = value; }
+ }
+
+ public Connection Connection
+ {
+ get { return this.connection; }
+ }
+
+ public SessionId SessionId
+ {
+ get { return info.SessionId; }
+ }
+
+ public TransactionContext TransactionContext
+ {
+ get { return this.transactionContext; }
+ }
- ~Session()
- {
- Dispose(false);
- }
-
- #region Property Accessors
-
- /// <summary>
- /// Sets the prefetch size, the maximum number of messages a
broker will dispatch to consumers
- /// until acknowledgements are received.
- /// </summary>
- public int PrefetchSize
- {
- set{ this.connection.PrefetchPolicy.SetAll(value); }
- }
-
- /// <summary>
- /// Sets the maximum number of messages to keep around per
consumer
- /// in addition to the prefetch window for non-durable topics
until messages
- /// will start to be evicted for slow consumers.
- /// Must be > 0 to enable this feature
- /// </summary>
- public int MaximumPendingMessageLimit
- {
- set{
this.connection.PrefetchPolicy.MaximumPendingMessageLimit = value; }
- }
-
- /// <summary>
- /// Enables or disables whether asynchronous dispatch should be
used by the broker
- /// </summary>
- public bool DispatchAsync
- {
- get{ return this.dispatchAsync; }
- set{ this.dispatchAsync = value; }
- }
-
- /// <summary>
- /// Enables or disables exclusive consumers when using queues.
An exclusive consumer means
- /// only one instance of a consumer is allowed to process
messages on a queue to preserve order
- /// </summary>
- public bool Exclusive
- {
- get{ return this.exclusive; }
- set{ this.exclusive = value; }
- }
-
- /// <summary>
- /// Enables or disables retroactive mode for consumers; i.e. do
they go back in time or not?
- /// </summary>
- public bool Retroactive
- {
- get{ return this.retroactive; }
- set{ this.retroactive = value; }
- }
-
- /// <summary>
- /// Sets the default consumer priority for consumers
- /// </summary>
- public byte Priority
- {
- get{ return this.priority; }
- set{ this.priority = value; }
- }
-
- public Connection Connection
- {
- get { return this.connection; }
- }
-
- public SessionId SessionId
- {
- get { return info.SessionId; }
- }
-
- public TransactionContext TransactionContext
- {
- get { return this.transactionContext; }
- }
-
- public TimeSpan RequestTimeout
- {
- get { return this.requestTimeout; }
- set { this.requestTimeout = value; }
- }
+ public TimeSpan RequestTimeout
+ {
+ get { return this.requestTimeout; }
+ set { this.requestTimeout = value; }
+ }
public bool Transacted
{
get { return this.IsTransacted; }
}
- public virtual AcknowledgementMode AcknowledgementMode
- {
- get { return this.acknowledgementMode; }
- }
-
- public virtual bool IsClientAcknowledge
- {
- get { return this.acknowledgementMode ==
AcknowledgementMode.ClientAcknowledge; }
- }
-
- public virtual bool IsAutoAcknowledge
- {
- get { return this.acknowledgementMode ==
AcknowledgementMode.AutoAcknowledge; }
- }
-
- public virtual bool IsDupsOkAcknowledge
- {
- get { return this.acknowledgementMode ==
AcknowledgementMode.DupsOkAcknowledge; }
- }
-
- public virtual bool IsIndividualAcknowledge
- {
- get { return this.acknowledgementMode ==
AcknowledgementMode.IndividualAcknowledge; }
- }
-
- public virtual bool IsTransacted
- {
- get{ return this.acknowledgementMode ==
AcknowledgementMode.Transactional; }
- }
-
- public SessionExecutor Executor
- {
- get { return this.executor; }
- }
-
- public long NextDeliveryId
- {
- get { return Interlocked.Increment(ref
this.nextDeliveryId); }
- }
-
- public long DisposeStopTimeout
- {
- get { return (long)
this.disposeStopTimeout.TotalMilliseconds; }
- set { this.disposeStopTimeout =
TimeSpan.FromMilliseconds(value); }
- }
-
- public long CloseStopTimeout
- {
- get { return (long)
this.closeStopTimeout.TotalMilliseconds; }
- set { this.closeStopTimeout =
TimeSpan.FromMilliseconds(value); }
- }
-
- private ConsumerTransformerDelegate consumerTransformer;
- /// <summary>
- /// A Delegate that is called each time a Message is dispatched
to allow the client to do
- /// any necessary transformations on the received message
before it is delivered.
- /// The Session instance sets the delegate on each Consumer it
creates.
- /// </summary>
- public ConsumerTransformerDelegate ConsumerTransformer
- {
- get { return this.consumerTransformer; }
- set { this.consumerTransformer = value; }
- }
-
- private ProducerTransformerDelegate producerTransformer;
- /// <summary>
- /// A delegate that is called each time a Message is sent from
this Producer which allows
- /// the application to perform any needed transformations on
the Message before it is sent.
- /// The Session instance sets the delegate on each Producer it
creates.
- /// </summary>
- public ProducerTransformerDelegate ProducerTransformer
- {
- get { return this.producerTransformer; }
- set { this.producerTransformer = value; }
- }
-
- #endregion
-
- #region ISession Members
-
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected void Dispose(bool disposing)
- {
- if(this.disposed)
- {
- return;
- }
-
- if(disposing)
- {
- // Dispose managed code here.
- }
-
- try
- {
- // Force a Stop when we are Disposing vs a
Normal Close.
- this.executor.Stop(this.disposeStopTimeout);
-
- Close();
- }
- catch
- {
- // Ignore network errors.
- }
-
- this.disposed = true;
- }
-
- public void Close()
- {
- lock(myLock)
- {
- if(this.closed)
- {
- return;
- }
+ public virtual AcknowledgementMode AcknowledgementMode
+ {
+ get { return this.acknowledgementMode; }
+ }
- try
- {
+ public virtual bool IsClientAcknowledge
+ {
+ get { return this.acknowledgementMode ==
AcknowledgementMode.ClientAcknowledge; }
+ }
+
+ public virtual bool IsAutoAcknowledge
+ {
+ get { return this.acknowledgementMode ==
AcknowledgementMode.AutoAcknowledge; }
+ }
+
+ public virtual bool IsDupsOkAcknowledge
+ {
+ get { return this.acknowledgementMode ==
AcknowledgementMode.DupsOkAcknowledge; }
+ }
+
+ public virtual bool IsIndividualAcknowledge
+ {
+ get { return this.acknowledgementMode ==
AcknowledgementMode.IndividualAcknowledge; }
+ }
+
+ public virtual bool IsTransacted
+ {
+ get{ return this.acknowledgementMode ==
AcknowledgementMode.Transactional; }
+ }
+
+ public SessionExecutor Executor
+ {
+ get { return this.executor; }
+ }
+
+ public long NextDeliveryId
+ {
+ get { return Interlocked.Increment(ref this.nextDeliveryId); }
+ }
+
+ public long DisposeStopTimeout
+ {
+ get { return (long) this.disposeStopTimeout.TotalMilliseconds; }
+ set { this.disposeStopTimeout = TimeSpan.FromMilliseconds(value); }
+ }
+
+ public long CloseStopTimeout
+ {
+ get { return (long) this.closeStopTimeout.TotalMilliseconds; }
+ set { this.closeStopTimeout = TimeSpan.FromMilliseconds(value); }
+ }
+
+ private ConsumerTransformerDelegate consumerTransformer;
+ /// <summary>
+ /// A Delegate that is called each time a Message is dispatched to
allow the client to do
+ /// any necessary transformations on the received message before it is
delivered.
+ /// The Session instance sets the delegate on each Consumer it creates.
+ /// </summary>
+ public ConsumerTransformerDelegate ConsumerTransformer
+ {
+ get { return this.consumerTransformer; }
+ set { this.consumerTransformer = value; }
+ }
+
+ private ProducerTransformerDelegate producerTransformer;
+ /// <summary>
+ /// A delegate that is called each time a Message is sent from this
Producer which allows
+ /// the application to perform any needed transformations on the
Message before it is sent.
+ /// The Session instance sets the delegate on each Producer it creates.
+ /// </summary>
+ public ProducerTransformerDelegate ProducerTransformer
+ {
+ get { return this.producerTransformer; }
+ set { this.producerTransformer = value; }
+ }
+
+ #endregion
+
+ #region ISession Members
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected void Dispose(bool disposing)
+ {
+ if(this.disposed)
+ {
+ return;
+ }
+
+ if(disposing)
+ {
+ // Dispose managed code here.
+ }
+
+ try
+ {
+ // Force a Stop when we are Disposing vs a Normal Close.
+ this.executor.Stop(this.disposeStopTimeout);
+
+ Close();
+ }
+ catch
+ {
+ // Ignore network errors.
+ }
+
+ this.disposed = true;
+ }
+
+ public void Close()
+ {
+ lock(myLock)
+ {
+ if(this.closed)
+ {
+ return;
+ }
+
+ try
+ {
if(transactionContext.InNetTransaction)
{
this.transactionContext.AddSynchronization(new
SessionCloseSynchronization(this));
}
else
{
- Tracer.InfoFormat("Closing The Session
with Id {0}", this.info.SessionId.ToString());
- DoClose();
- Tracer.InfoFormat("Closed The Session
with Id {0}", this.info.SessionId.ToString());
+ Tracer.InfoFormat("Closing The Session with Id {0}",
this.info.SessionId.ToString());
+ DoClose();
+ Tracer.InfoFormat("Closed The Session with Id {0}",
this.info.SessionId.ToString());
+ }
+ }
+ catch(Exception ex)
+ {
+ Tracer.ErrorFormat("Error during session close: {0}", ex);
+ }
+ }
+ }
+
+ internal void DoClose()
+ {
+ lock(myLock)
+ {
+ if(this.closed)
+ {
+ return;
+ }
+
+ try
+ {
+ this.closing = true;
+
+ // Stop all message deliveries from this Session
+ this.executor.Stop(this.closeStopTimeout);
+
+ lock(consumers.SyncRoot)
+ {
+ foreach(MessageConsumer consumer in consumers.Values)
+ {
+ consumer.DoClose();
+ this.lastDeliveredSequenceId =
+ Math.Min(this.lastDeliveredSequenceId,
consumer.LastDeliveredSequenceId);
+ }
}
- }
- catch(Exception ex)
- {
- Tracer.ErrorFormat("Error during
session close: {0}", ex);
- }
- }
- }
-
- internal void DoClose()
- {
- lock(myLock)
- {
- if(this.closed)
- {
- return;
- }
-
- try
- {
- this.closing = true;
-
- // Stop all message deliveries from
this Session
-
this.executor.Stop(this.closeStopTimeout);
-
- lock(consumers.SyncRoot)
- {
- foreach(MessageConsumer
consumer in consumers.Values)
- {
- consumer.DoClose();
-
this.lastDeliveredSequenceId =
-
Math.Min(this.lastDeliveredSequenceId, consumer.LastDeliveredSequenceId);
- }
- }
- consumers.Clear();
-
- lock(producers.SyncRoot)
- {
- foreach(MessageProducer
producer in producers.Values)
- {
- producer.DoClose();
- }
- }
- producers.Clear();
-
- // If in a transaction roll it back
- if(this.IsTransacted &&
this.transactionContext.InTransaction)
- {
- try
- {
-
this.transactionContext.Rollback();
- }
- catch
- {
- }
- }
-
- Connection.RemoveSession(this);
- }
- catch(Exception ex)
- {
- Tracer.ErrorFormat("Error during
session close: {0}", ex);
- }
- finally
- {
+ consumers.Clear();
+
+ lock(producers.SyncRoot)
+ {
+ foreach(MessageProducer producer in producers.Values)
+ {
+ producer.DoClose();
+ }
+ }
+ producers.Clear();
+
+ // If in a transaction roll it back
+ if(this.IsTransacted &&
this.transactionContext.InTransaction)
+ {
+ try
+ {
+ this.transactionContext.Rollback();
+ }
+ catch
+ {
+ }
+ }
+
+ Connection.RemoveSession(this);
+ }
+ catch(Exception ex)
+ {
+ Tracer.ErrorFormat("Error during session close: {0}", ex);
+ }
+ finally
+ {
// Make sure we attempt to inform the broker this Session
is done.
RemoveInfo info = new RemoveInfo();
info.ObjectId = this.info.SessionId;
@@ -393,325 +393,325 @@ namespace Apache.NMS.ActiveMQ
this.connection = null;
this.closed = true;
this.closing = false;
- }
- }
- }
-
- public IMessageProducer CreateProducer()
- {
- return CreateProducer(null);
- }
-
- public IMessageProducer CreateProducer(IDestination destination)
- {
- MessageProducer producer = null;
-
- try
- {
- ActiveMQDestination dest = null;
- if(destination != null)
- {
- dest =
ActiveMQDestination.Transform(destination);
- }
-
- producer = new MessageProducer(this,
GetNextProducerId(), dest, this.RequestTimeout);
-
- producer.ProducerTransformer =
this.ProducerTransformer;
-
- this.AddProducer(producer);
- this.Connection.Oneway(producer.ProducerInfo);
- }
- catch(Exception)
- {
- if(producer != null)
- {
-
this.RemoveProducer(producer.ProducerId);
- producer.Close();
- }
-
- throw;
- }
-
- return producer;
- }
-
- public IMessageConsumer CreateConsumer(IDestination destination)
- {
- return CreateConsumer(destination, null, false);
- }
-
- public IMessageConsumer CreateConsumer(IDestination
destination, string selector)
- {
- return CreateConsumer(destination, selector, false);
- }
-
- public IMessageConsumer CreateConsumer(IDestination
destination, string selector, bool noLocal)
- {
- if(destination == null)
- {
- throw new InvalidDestinationException("Cannot
create a Consumer with a Null destination");
- }
-
- ActiveMQDestination dest =
ActiveMQDestination.Transform(destination);
- int prefetchSize =
this.Connection.PrefetchPolicy.DurableTopicPrefetch;
-
- if(dest is ITopic || dest is ITemporaryTopic)
- {
- prefetchSize =
this.connection.PrefetchPolicy.TopicPrefetch;
- }
- else if(dest is IQueue || dest is ITemporaryQueue)
- {
- prefetchSize =
this.connection.PrefetchPolicy.QueuePrefetch;
- }
-
- MessageConsumer consumer = null;
-
- try
- {
- consumer = new MessageConsumer(this,
GetNextConsumerId(), dest, null, selector, prefetchSize,
-
this.connection.PrefetchPolicy.MaximumPendingMessageLimit,
-
noLocal, false, this.connection.DispatchAsync);
-
- consumer.ConsumerTransformer =
this.ConsumerTransformer;
-
- this.AddConsumer(consumer);
-
this.Connection.SyncRequest(consumer.ConsumerInfo);
-
- if(this.Connection.IsStarted)
- {
- consumer.Start();
- }
- }
- catch(Exception)
- {
- if(consumer != null)
- {
-
this.RemoveConsumer(consumer.ConsumerId);
- consumer.Close();
- }
-
- throw;
- }
-
- return consumer;
- }
-
- public IMessageConsumer CreateDurableConsumer(ITopic
destination, string name, string selector, bool noLocal)
- {
- if(destination == null)
- {
- throw new InvalidDestinationException("Cannot
create a Consumer with a Null destination");
- }
-
- ActiveMQDestination dest =
ActiveMQDestination.Transform(destination);
- MessageConsumer consumer = null;
-
- try
- {
- consumer = new MessageConsumer(this,
GetNextConsumerId(), dest, name, selector,
-
this.connection.PrefetchPolicy.DurableTopicPrefetch,
-
this.connection.PrefetchPolicy.MaximumPendingMessageLimit,
-
noLocal, false, this.connection.DispatchAsync);
-
- consumer.ConsumerTransformer =
this.ConsumerTransformer;
-
- this.AddConsumer(consumer);
-
this.Connection.SyncRequest(consumer.ConsumerInfo);
-
- if(this.Connection.IsStarted)
- {
- consumer.Start();
- }
- }
- catch(Exception)
- {
- if(consumer != null)
- {
-
this.RemoveConsumer(consumer.ConsumerId);
- consumer.Close();
- }
-
- throw;
- }
-
- return consumer;
- }
-
- public void DeleteDurableConsumer(string name)
- {
- RemoveSubscriptionInfo command = new
RemoveSubscriptionInfo();
- command.ConnectionId = Connection.ConnectionId;
- command.ClientId = Connection.ClientId;
- command.SubcriptionName = name;
- this.connection.SyncRequest(command);
- }
-
- public IQueueBrowser CreateBrowser(IQueue queue)
- {
- return this.CreateBrowser(queue, null);
- }
-
- public IQueueBrowser CreateBrowser(IQueue queue, string
selector)
- {
- if(queue == null)
- {
- throw new InvalidDestinationException("Cannot
create a Consumer with a Null destination");
- }
-
- ActiveMQDestination dest =
ActiveMQDestination.Transform(queue);
- QueueBrowser browser = null;
-
- try
- {
- browser = new QueueBrowser(this,
GetNextConsumerId(), dest, selector, this.DispatchAsync);
- }
- catch(Exception)
- {
- if(browser != null)
- {
- browser.Close();
- }
-
- throw;
- }
-
- return browser;
- }
-
- public IQueue GetQueue(string name)
- {
- return new ActiveMQQueue(name);
- }
-
- public ITopic GetTopic(string name)
- {
- return new ActiveMQTopic(name);
- }
-
- public ITemporaryQueue CreateTemporaryQueue()
- {
- return
(ITemporaryQueue)this.connection.CreateTemporaryDestination(false);
- }
-
- public ITemporaryTopic CreateTemporaryTopic()
- {
- return
(ITemporaryTopic)this.connection.CreateTemporaryDestination(true);
- }
-
- /// <summary>
- /// Delete a destination (Queue, Topic, Temp Queue, Temp Topic).
- /// </summary>
- public void DeleteDestination(IDestination destination)
- {
- this.connection.DeleteDestination(destination);
- }
-
- public IMessage CreateMessage()
- {
- ActiveMQMessage answer = new ActiveMQMessage();
- return ConfigureMessage(answer) as IMessage;
- }
-
- public ITextMessage CreateTextMessage()
- {
- ActiveMQTextMessage answer = new ActiveMQTextMessage();
- return ConfigureMessage(answer) as ITextMessage;
- }
-
- public ITextMessage CreateTextMessage(string text)
- {
- ActiveMQTextMessage answer = new
ActiveMQTextMessage(text);
- return ConfigureMessage(answer) as ITextMessage;
- }
-
- public IMapMessage CreateMapMessage()
- {
- return ConfigureMessage(new ActiveMQMapMessage()) as
IMapMessage;
- }
-
- public IBytesMessage CreateBytesMessage()
- {
- return ConfigureMessage(new ActiveMQBytesMessage()) as
IBytesMessage;
- }
-
- public IBytesMessage CreateBytesMessage(byte[] body)
- {
- ActiveMQBytesMessage answer = new
ActiveMQBytesMessage();
- answer.Content = body;
- return ConfigureMessage(answer) as IBytesMessage;
- }
-
- public IStreamMessage CreateStreamMessage()
- {
- return ConfigureMessage(new ActiveMQStreamMessage()) as
IStreamMessage;
- }
-
- public IObjectMessage CreateObjectMessage(object body)
- {
- ActiveMQObjectMessage answer = new
ActiveMQObjectMessage();
- answer.Body = body;
- return ConfigureMessage(answer) as IObjectMessage;
- }
+ }
+ }
+ }
+
+ public IMessageProducer CreateProducer()
+ {
+ return CreateProducer(null);
+ }
+
+ public IMessageProducer CreateProducer(IDestination destination)
+ {
+ MessageProducer producer = null;
+
+ try
+ {
+ ActiveMQDestination dest = null;
+ if(destination != null)
+ {
+ dest = ActiveMQDestination.Transform(destination);
+ }
+
+ producer = new MessageProducer(this, GetNextProducerId(),
dest, this.RequestTimeout);
+
+ producer.ProducerTransformer = this.ProducerTransformer;
+
+ this.AddProducer(producer);
+ this.Connection.Oneway(producer.ProducerInfo);
+ }
+ catch(Exception)
+ {
+ if(producer != null)
+ {
+ this.RemoveProducer(producer.ProducerId);
+ producer.Close();
+ }
+
+ throw;
+ }
+
+ return producer;
+ }
+
+ public IMessageConsumer CreateConsumer(IDestination destination)
+ {
+ return CreateConsumer(destination, null, false);
+ }
+
+ public IMessageConsumer CreateConsumer(IDestination destination,
string selector)
+ {
+ return CreateConsumer(destination, selector, false);
+ }
+
+ public IMessageConsumer CreateConsumer(IDestination destination,
string selector, bool noLocal)
+ {
+ if(destination == null)
+ {
+ throw new InvalidDestinationException("Cannot create a
Consumer with a Null destination");
+ }
+
+ ActiveMQDestination dest =
ActiveMQDestination.Transform(destination);
+ int prefetchSize =
this.Connection.PrefetchPolicy.DurableTopicPrefetch;
+
+ if(dest is ITopic || dest is ITemporaryTopic)
+ {
+ prefetchSize = this.connection.PrefetchPolicy.TopicPrefetch;
+ }
+ else if(dest is IQueue || dest is ITemporaryQueue)
+ {
+ prefetchSize = this.connection.PrefetchPolicy.QueuePrefetch;
+ }
+
+ MessageConsumer consumer = null;
+
+ try
+ {
+ consumer = new MessageConsumer(this, GetNextConsumerId(),
dest, null, selector, prefetchSize,
+
this.connection.PrefetchPolicy.MaximumPendingMessageLimit,
+ noLocal, false,
this.connection.DispatchAsync);
+
+ consumer.ConsumerTransformer = this.ConsumerTransformer;
+
+ this.AddConsumer(consumer);
+ this.Connection.SyncRequest(consumer.ConsumerInfo);
+
+ if(this.Connection.IsStarted)
+ {
+ consumer.Start();
+ }
+ }
+ catch(Exception)
+ {
+ if(consumer != null)
+ {
+ this.RemoveConsumer(consumer.ConsumerId);
+ consumer.Close();
+ }
+
+ throw;
+ }
+
+ return consumer;
+ }
+
+ public IMessageConsumer CreateDurableConsumer(ITopic destination,
string name, string selector, bool noLocal)
+ {
+ if(destination == null)
+ {
+ throw new InvalidDestinationException("Cannot create a
Consumer with a Null destination");
+ }
+
+ ActiveMQDestination dest =
ActiveMQDestination.Transform(destination);
+ MessageConsumer consumer = null;
+
+ try
+ {
+ consumer = new MessageConsumer(this, GetNextConsumerId(),
dest, name, selector,
+
this.connection.PrefetchPolicy.DurableTopicPrefetch,
+
this.connection.PrefetchPolicy.MaximumPendingMessageLimit,
+ noLocal, false,
this.connection.DispatchAsync);
+
+ consumer.ConsumerTransformer = this.ConsumerTransformer;
+
+ this.AddConsumer(consumer);
+ this.Connection.SyncRequest(consumer.ConsumerInfo);
+
+ if(this.Connection.IsStarted)
+ {
+ consumer.Start();
+ }
+ }
+ catch(Exception)
+ {
+ if(consumer != null)
+ {
+ this.RemoveConsumer(consumer.ConsumerId);
+ consumer.Close();
+ }
+
+ throw;
+ }
+
+ return consumer;
+ }
+
+ public void DeleteDurableConsumer(string name)
+ {
+ RemoveSubscriptionInfo command = new RemoveSubscriptionInfo();
+ command.ConnectionId = Connection.ConnectionId;
+ command.ClientId = Connection.ClientId;
+ command.SubcriptionName = name;
+ this.connection.SyncRequest(command);
+ }
+
+ public IQueueBrowser CreateBrowser(IQueue queue)
+ {
+ return this.CreateBrowser(queue, null);
+ }
+
+ public IQueueBrowser CreateBrowser(IQueue queue, string selector)
+ {
+ if(queue == null)
+ {
+ throw new InvalidDestinationException("Cannot create a
Consumer with a Null destination");
+ }
+
+ ActiveMQDestination dest = ActiveMQDestination.Transform(queue);
+ QueueBrowser browser = null;
+
+ try
+ {
+ browser = new QueueBrowser(this, GetNextConsumerId(), dest,
selector, this.DispatchAsync);
+ }
+ catch(Exception)
+ {
+ if(browser != null)
+ {
+ browser.Close();
+ }
+
+ throw;
+ }
+
+ return browser;
+ }
+
+ public IQueue GetQueue(string name)
+ {
+ return new ActiveMQQueue(name);
+ }
+
+ public ITopic GetTopic(string name)
+ {
+ return new ActiveMQTopic(name);
+ }
+
+ public ITemporaryQueue CreateTemporaryQueue()
+ {
+ return
(ITemporaryQueue)this.connection.CreateTemporaryDestination(false);
+ }
+
+ public ITemporaryTopic CreateTemporaryTopic()
+ {
+ return
(ITemporaryTopic)this.connection.CreateTemporaryDestination(true);
+ }
+
+ /// <summary>
+ /// Delete a destination (Queue, Topic, Temp Queue, Temp Topic).
+ /// </summary>
+ public void DeleteDestination(IDestination destination)
+ {
+ this.connection.DeleteDestination(destination);
+ }
+
+ public IMessage CreateMessage()
+ {
+ ActiveMQMessage answer = new ActiveMQMessage();
+ return ConfigureMessage(answer) as IMessage;
+ }
+
+ public ITextMessage CreateTextMessage()
+ {
+ ActiveMQTextMessage answer = new ActiveMQTextMessage();
+ return ConfigureMessage(answer) as ITextMessage;
+ }
+
+ public ITextMessage CreateTextMessage(string text)
+ {
+ ActiveMQTextMessage answer = new ActiveMQTextMessage(text);
+ return ConfigureMessage(answer) as ITextMessage;
+ }
+
+ public IMapMessage CreateMapMessage()
+ {
+ return ConfigureMessage(new ActiveMQMapMessage()) as IMapMessage;
+ }
+
+ public IBytesMessage CreateBytesMessage()
+ {
+ return ConfigureMessage(new ActiveMQBytesMessage()) as
IBytesMessage;
+ }
+
+ public IBytesMessage CreateBytesMessage(byte[] body)
+ {
+ ActiveMQBytesMessage answer = new ActiveMQBytesMessage();
+ answer.Content = body;
+ return ConfigureMessage(answer) as IBytesMessage;
+ }
- public void Commit()
- {
+ public IStreamMessage CreateStreamMessage()
+ {
+ return ConfigureMessage(new ActiveMQStreamMessage()) as
IStreamMessage;
+ }
+
+ public IObjectMessage CreateObjectMessage(object body)
+ {
+ ActiveMQObjectMessage answer = new ActiveMQObjectMessage();
+ answer.Body = body;
+ return ConfigureMessage(answer) as IObjectMessage;
+ }
+
+ public void Commit()
+ {
this.DoCommit();
- }
+ }
- public void Rollback()
- {
+ public void Rollback()
+ {
this.DoRollback();
- }
+ }
+
+ #endregion
- #endregion
+ internal void DoSend( ActiveMQMessage message, MessageProducer
producer, MemoryUsage producerWindow, TimeSpan sendTimeout )
+ {
+ ActiveMQMessage msg = message;
+
+ if(IsTransacted)
+ {
+ DoStartTransaction();
+ msg.TransactionId = TransactionContext.TransactionId;
+ }
- internal void DoSend( ActiveMQMessage message, MessageProducer
producer, MemoryUsage producerWindow, TimeSpan sendTimeout )
- {
- ActiveMQMessage msg = message;
-
- if(IsTransacted)
- {
- DoStartTransaction();
- msg.TransactionId =
TransactionContext.TransactionId;
- }
-
- msg.RedeliveryCounter = 0;
- msg.BrokerPath = null;
-
- if(this.connection.CopyMessageOnSend)
- {
- msg = (ActiveMQMessage)msg.Clone();
- }
-
- msg.OnSend();
- msg.ProducerId = msg.MessageId.ProducerId;
-
- if(sendTimeout.TotalMilliseconds <= 0 &&
!msg.ResponseRequired && !connection.AlwaysSyncSend &&
- (!msg.Persistent || connection.AsyncSend ||
msg.TransactionId != null))
- {
- this.connection.Oneway(msg);
-
- if(producerWindow != null)
- {
- // Since we defer lots of the
marshaling till we hit the wire, this
- // might not provide and accurate size.
We may change over to doing
- // more aggressive marshaling, to get
more accurate sizes.. this is more
- // important once users start using
producer window flow control.
-
producerWindow.IncreaseUsage(msg.Size());
- }
- }
- else
- {
- if(sendTimeout.TotalMilliseconds > 0)
- {
- this.connection.SyncRequest(msg,
sendTimeout);
- }
- else
- {
- this.connection.SyncRequest(msg);
- }
- }
- }
+ msg.RedeliveryCounter = 0;
+ msg.BrokerPath = null;
+
+ if(this.connection.CopyMessageOnSend)
+ {
+ msg = (ActiveMQMessage)msg.Clone();
+ }
+
+ msg.OnSend();
+ msg.ProducerId = msg.MessageId.ProducerId;
+
+ if(sendTimeout.TotalMilliseconds <= 0 && !msg.ResponseRequired &&
!connection.AlwaysSyncSend &&
+ (!msg.Persistent || connection.AsyncSend || msg.TransactionId
!= null))
+ {
+ this.connection.Oneway(msg);
+
+ if(producerWindow != null)
+ {
+ // Since we defer lots of the marshaling till we hit the
wire, this
+ // might not provide and accurate size. We may change over
to doing
+ // more aggressive marshaling, to get more accurate
sizes.. this is more
+ // important once users start using producer window flow
control.
+ producerWindow.IncreaseUsage(msg.Size());
+ }
+ }
+ else
+ {
+ if(sendTimeout.TotalMilliseconds > 0)
+ {
+ this.connection.SyncRequest(msg, sendTimeout);
+ }
+ else
+ {
+ this.connection.SyncRequest(msg);
+ }
+ }
+ }
internal virtual void DoCommit()
{
@@ -737,205 +737,212 @@ namespace Apache.NMS.ActiveMQ
this.TransactionContext.Rollback();
}
- /// <summary>
- /// Ensures that a transaction is started
- /// </summary>
- internal virtual void DoStartTransaction()
- {
- if(IsTransacted)
- {
- this.TransactionContext.Begin();
- }
- }
-
- public void AddConsumer(MessageConsumer consumer)
- {
- ConsumerId id = consumer.ConsumerId;
-
- // Registered with Connection before we register at the
broker.
- consumers[id] = consumer;
- connection.addDispatcher(id, this);
- }
-
- public void RemoveConsumer(ConsumerId objectId)
- {
- connection.removeDispatcher(objectId);
- if(!this.closing)
- {
- consumers.Remove(objectId);
- }
- }
-
- public void AddProducer(MessageProducer producer)
- {
- ProducerId id = producer.ProducerId;
-
- this.producers[id] = producer;
- this.connection.addProducer(id, producer);
- }
-
- public void RemoveProducer(ProducerId objectId)
- {
- connection.removeProducer(objectId);
- if(!this.closing)
- {
- producers.Remove(objectId);
- }
- }
-
- public ConsumerId GetNextConsumerId()
- {
- ConsumerId id = new ConsumerId();
- id.ConnectionId = info.SessionId.ConnectionId;
- id.SessionId = info.SessionId.Value;
- id.Value = Interlocked.Increment(ref consumerCounter);
-
- return id;
- }
-
- public ProducerId GetNextProducerId()
- {
- ProducerId id = new ProducerId();
- id.ConnectionId = info.SessionId.ConnectionId;
- id.SessionId = info.SessionId.Value;
- id.Value = Interlocked.Increment(ref producerCounter);
-
- return id;
- }
-
- public void Stop()
- {
- if(this.executor != null)
- {
- this.executor.Stop();
- }
- }
-
- public void Start()
- {
- foreach(MessageConsumer consumer in
this.consumers.Values)
- {
- consumer.Start();
- }
-
- if(this.executor != null)
- {
- this.executor.Start();
- }
- }
-
- public bool Started
- {
- get
- {
- return this.executor != null ?
this.executor.Running : false;
- }
- }
-
- internal void Redispatch(MessageDispatchChannel channel)
- {
- MessageDispatch[] messages = channel.RemoveAll();
- System.Array.Reverse(messages);
-
- foreach(MessageDispatch message in messages)
- {
- this.executor.ExecuteFirst(message);
- }
- }
-
- public void Dispatch(MessageDispatch dispatch)
- {
- if(this.executor != null)
- {
- this.executor.Execute(dispatch);
- }
- }
-
- internal void ClearMessagesInProgress()
- {
- if( this.executor != null ) {
- this.executor.ClearMessagesInProgress();
- }
-
- // Because we are called from inside the Transport
Reconnection logic
- // we spawn the Consumer clear to another Thread so
that we can avoid
- // any lock contention that might exist between the
consumer and the
- // connection that is reconnecting.
- lock(this.consumers.SyncRoot)
- {
- foreach(MessageConsumer consumer in
this.consumers.Values)
- {
- consumer.InProgressClearRequired();
-
ThreadPool.QueueUserWorkItem(ClearMessages, consumer);
- }
- }
- }
-
- private void ClearMessages(object value)
- {
- MessageConsumer consumer = value as MessageConsumer;
-
- if(Tracer.IsDebugEnabled)
- {
- Tracer.Debug("Performing Async Clear of In
Progress Messages on Consumer: " + consumer.ConsumerId);
- }
-
- consumer.ClearMessagesInProgress();
- }
-
- internal void Acknowledge()
- {
- lock(this.consumers.SyncRoot)
- {
- foreach(MessageConsumer consumer in
this.consumers.Values)
- {
- consumer.Acknowledge();
- }
- }
- }
-
- private ActiveMQMessage ConfigureMessage(ActiveMQMessage
message)
- {
- message.Connection = this.connection;
-
- if(this.IsTransacted)
- {
- // Allows Acknowledge to be called in a
transaction with no effect per JMS Spec.
- message.Acknowledger += new
AcknowledgeHandler(DoNothingAcknowledge);
- }
-
- return message;
- }
-
- internal void SendAck(MessageAck ack)
- {
- this.SendAck(ack, false);
- }
-
- internal void SendAck(MessageAck ack, bool lazy)
- {
- if(lazy || connection.SendAcksAsync ||
this.IsTransacted )
- {
- this.connection.Oneway(ack);
- }
- else
- {
- this.connection.SyncRequest(ack);
- }
- }
-
- /// <summary>
- /// Prevents message from throwing an exception if a client
calls Acknoweldge on
- /// a message that is part of a transaction either being
produced or consumed. The
- /// JMS Spec indicates that users should be able to call
Acknowledge with no effect
- /// if the message is in a transaction.
- /// </summary>
- /// <param name="message">
- /// A <see cref="ActiveMQMessage"/>
- /// </param>
- private void DoNothingAcknowledge(ActiveMQMessage message)
- {
- }
+ /// <summary>
+ /// Ensures that a transaction is started
+ /// </summary>
+ internal virtual void DoStartTransaction()
+ {
+ if(IsTransacted)
+ {
+ this.TransactionContext.Begin();
+ }
+ }
+
+ public void AddConsumer(MessageConsumer consumer)
+ {
+ if(!this.closing)
+ {
+ ConsumerId id = consumer.ConsumerId;
+
+ // Registered with Connection before we register at the broker.
+ consumers[id] = consumer;
+ connection.addDispatcher(id, this);
+ }
+ }
+
+ public void RemoveConsumer(ConsumerId objectId)
+ {
+ connection.removeDispatcher(objectId);
+ if(!this.closing)
+ {
+ consumers.Remove(objectId);
+ }
+ }
+
+ public void AddProducer(MessageProducer producer)
+ {
+ if(!this.closing)
+ {
+ ProducerId id = producer.ProducerId;
+
+ this.producers[id] = producer;
+ this.connection.addProducer(id, producer);
+ }
+ }
+
+ public void RemoveProducer(ProducerId objectId)
+ {
+ connection.removeProducer(objectId);
+ if(!this.closing)
+ {
+ producers.Remove(objectId);
+ }
+ }
+
+ public ConsumerId GetNextConsumerId()
+ {
+ ConsumerId id = new ConsumerId();
+ id.ConnectionId = info.SessionId.ConnectionId;
+ id.SessionId = info.SessionId.Value;
+ id.Value = Interlocked.Increment(ref consumerCounter);
+
+ return id;
+ }
+
+ public ProducerId GetNextProducerId()
+ {
+ ProducerId id = new ProducerId();
+ id.ConnectionId = info.SessionId.ConnectionId;
+ id.SessionId = info.SessionId.Value;
+ id.Value = Interlocked.Increment(ref producerCounter);
+
+ return id;
+ }
+
+ public void Stop()
+ {
+ if(this.executor != null)
+ {
+ this.executor.Stop();
+ }
+ }
+
+ public void Start()
+ {
+ foreach(MessageConsumer consumer in this.consumers.Values)
+ {
+ consumer.Start();
+ }
+
+ if(this.executor != null)
+ {
+ this.executor.Start();
+ }
+ }
+
+ public bool Started
+ {
+ get
+ {
+ return this.executor != null ? this.executor.Running : false;
+ }
+ }
+
+ internal void Redispatch(MessageDispatchChannel channel)
+ {
+ MessageDispatch[] messages = channel.RemoveAll();
+ System.Array.Reverse(messages);
+
+ foreach(MessageDispatch message in messages)
+ {
+ this.executor.ExecuteFirst(message);
+ }
+ }
+
+ public void Dispatch(MessageDispatch dispatch)
+ {
+ if(this.executor != null)
+ {
+ this.executor.Execute(dispatch);
+ }
+ }
+
+ internal void ClearMessagesInProgress()
+ {
+ if(this.executor != null)
+ {
+ this.executor.ClearMessagesInProgress();
+ }
+
+ // Because we are called from inside the Transport Reconnection
logic
+ // we spawn the Consumer clear to another Thread so that we can
avoid
+ // any lock contention that might exist between the consumer and
the
+ // connection that is reconnecting.
+ lock(this.consumers.SyncRoot)
+ {
+ foreach(MessageConsumer consumer in this.consumers.Values)
+ {
+ consumer.InProgressClearRequired();
+ ThreadPool.QueueUserWorkItem(ClearMessages, consumer);
+ }
+ }
+ }
+
+ private void ClearMessages(object value)
+ {
+ MessageConsumer consumer = value as MessageConsumer;
+
+ if(Tracer.IsDebugEnabled)
+ {
+ Tracer.Debug("Performing Async Clear of In Progress Messages
on Consumer: " + consumer.ConsumerId);
+ }
+
+ consumer.ClearMessagesInProgress();
+ }
+
+ internal void Acknowledge()
+ {
+ lock(this.consumers.SyncRoot)
+ {
+ foreach(MessageConsumer consumer in this.consumers.Values)
+ {
+ consumer.Acknowledge();
+ }
+ }
+ }
+
+ private ActiveMQMessage ConfigureMessage(ActiveMQMessage message)
+ {
+ message.Connection = this.connection;
+
+ if(this.IsTransacted)
+ {
+ // Allows Acknowledge to be called in a transaction with no
effect per JMS Spec.
+ message.Acknowledger += new
AcknowledgeHandler(DoNothingAcknowledge);
+ }
+
+ return message;
+ }
+
+ internal void SendAck(MessageAck ack)
+ {
+ this.SendAck(ack, false);
+ }
+
+ internal void SendAck(MessageAck ack, bool lazy)
+ {
+ if(lazy || connection.SendAcksAsync || this.IsTransacted )
+ {
+ this.connection.Oneway(ack);
+ }
+ else
+ {
+ this.connection.SyncRequest(ack);
+ }
+ }
+
+ /// <summary>
+ /// Prevents message from throwing an exception if a client calls
Acknoweldge on
+ /// a message that is part of a transaction either being produced or
consumed. The
+ /// JMS Spec indicates that users should be able to call Acknowledge
with no effect
+ /// if the message is in a transaction.
+ /// </summary>
+ /// <param name="message">
+ /// A <see cref="ActiveMQMessage"/>
+ /// </param>
+ private void DoNothingAcknowledge(ActiveMQMessage message)
+ {
+ }
class SessionCloseSynchronization : ISynchronization
{
@@ -961,5 +968,5 @@ namespace Apache.NMS.ActiveMQ
}
}
- }
+ }
}