mirror of https://github.com/apache/activemq.git
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@729939 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8242a3f58c
commit
63e3f41af2
|
@ -28,31 +28,29 @@ import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.usage.SystemUsage;
|
import org.apache.activemq.usage.SystemUsage;
|
||||||
import org.apache.activemq.usage.Usage;
|
import org.apache.activemq.usage.Usage;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @version $Revision: 1.12 $
|
* @version $Revision: 1.12 $
|
||||||
*/
|
*/
|
||||||
public abstract class BaseDestination implements Destination {
|
public abstract class BaseDestination implements Destination {
|
||||||
/**
|
/**
|
||||||
* The maximum number of messages to page in to the destination
|
* The maximum number of messages to page in to the destination from persistent storage
|
||||||
* from persistent storage
|
|
||||||
*/
|
*/
|
||||||
public static final int MAX_PAGE_SIZE=200;
|
public static final int MAX_PAGE_SIZE = 200;
|
||||||
public static final int MAX_BROWSE_PAGE_SIZE=MAX_PAGE_SIZE*2;
|
public static final int MAX_BROWSE_PAGE_SIZE = MAX_PAGE_SIZE * 2;
|
||||||
protected final ActiveMQDestination destination;
|
protected final ActiveMQDestination destination;
|
||||||
protected final Broker broker;
|
protected final Broker broker;
|
||||||
protected final MessageStore store;
|
protected final MessageStore store;
|
||||||
protected SystemUsage systemUsage;
|
protected SystemUsage systemUsage;
|
||||||
protected MemoryUsage memoryUsage;
|
protected MemoryUsage memoryUsage;
|
||||||
private boolean producerFlowControl = true;
|
private boolean producerFlowControl = true;
|
||||||
private int maxProducersToAudit=1024;
|
private int maxProducersToAudit = 1024;
|
||||||
private int maxAuditDepth=2048;
|
private int maxAuditDepth = 2048;
|
||||||
private boolean enableAudit=true;
|
private boolean enableAudit = true;
|
||||||
private int maxPageSize=MAX_PAGE_SIZE;
|
private int maxPageSize = MAX_PAGE_SIZE;
|
||||||
private int maxBrowsePageSize=MAX_BROWSE_PAGE_SIZE;
|
private int maxBrowsePageSize = MAX_BROWSE_PAGE_SIZE;
|
||||||
private boolean useCache=true;
|
private boolean useCache = true;
|
||||||
private int minimumMessageSize=1024;
|
private int minimumMessageSize = 1024;
|
||||||
private boolean lazyDispatch=false;
|
private boolean lazyDispatch = false;
|
||||||
private boolean advisoryForSlowConsumers;
|
private boolean advisoryForSlowConsumers;
|
||||||
private boolean advisdoryForFastProducers;
|
private boolean advisdoryForFastProducers;
|
||||||
private boolean advisoryForDiscardingMessages;
|
private boolean advisoryForDiscardingMessages;
|
||||||
|
@ -63,31 +61,32 @@ public abstract class BaseDestination implements Destination {
|
||||||
protected final BrokerService brokerService;
|
protected final BrokerService brokerService;
|
||||||
protected final Broker regionBroker;
|
protected final Broker regionBroker;
|
||||||
protected DeadLetterStrategy deadLetterStrategy = DEFAULT_DEAD_LETTER_STRATEGY;
|
protected DeadLetterStrategy deadLetterStrategy = DEFAULT_DEAD_LETTER_STRATEGY;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param broker
|
* @param broker
|
||||||
* @param store
|
* @param store
|
||||||
* @param destination
|
* @param destination
|
||||||
* @param parentStats
|
* @param parentStats
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public BaseDestination(BrokerService brokerService,MessageStore store, ActiveMQDestination destination, DestinationStatistics parentStats) throws Exception {
|
public BaseDestination(BrokerService brokerService, MessageStore store, ActiveMQDestination destination,
|
||||||
|
DestinationStatistics parentStats) throws Exception {
|
||||||
this.brokerService = brokerService;
|
this.brokerService = brokerService;
|
||||||
this.broker=brokerService.getBroker();
|
this.broker = brokerService.getBroker();
|
||||||
this.store=store;
|
this.store = store;
|
||||||
this.destination=destination;
|
this.destination = destination;
|
||||||
// let's copy the enabled property from the parent DestinationStatistics
|
// let's copy the enabled property from the parent DestinationStatistics
|
||||||
this.destinationStatistics.setEnabled(parentStats.isEnabled());
|
this.destinationStatistics.setEnabled(parentStats.isEnabled());
|
||||||
this.destinationStatistics.setParent(parentStats);
|
this.destinationStatistics.setParent(parentStats);
|
||||||
|
|
||||||
this.systemUsage = brokerService.getProducerSystemUsage();
|
this.systemUsage = brokerService.getProducerSystemUsage();
|
||||||
this.memoryUsage = new MemoryUsage(systemUsage.getMemoryUsage(), destination.toString());
|
this.memoryUsage = new MemoryUsage(systemUsage.getMemoryUsage(), destination.toString());
|
||||||
this.memoryUsage.setUsagePortion(1.0f);
|
this.memoryUsage.setUsagePortion(1.0f);
|
||||||
this.regionBroker = brokerService.getRegionBroker();
|
this.regionBroker = brokerService.getRegionBroker();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initialize the destination
|
* initialize the destination
|
||||||
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void initialize() throws Exception {
|
public void initialize() throws Exception {
|
||||||
|
@ -95,66 +94,77 @@ public abstract class BaseDestination implements Destination {
|
||||||
// flush messages to disk when usage gets high.
|
// flush messages to disk when usage gets high.
|
||||||
if (store != null) {
|
if (store != null) {
|
||||||
store.setMemoryUsage(this.memoryUsage);
|
store.setMemoryUsage(this.memoryUsage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the producerFlowControl
|
* @return the producerFlowControl
|
||||||
*/
|
*/
|
||||||
public boolean isProducerFlowControl() {
|
public boolean isProducerFlowControl() {
|
||||||
return producerFlowControl;
|
return producerFlowControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param producerFlowControl the producerFlowControl to set
|
* @param producerFlowControl
|
||||||
|
* the producerFlowControl to set
|
||||||
*/
|
*/
|
||||||
public void setProducerFlowControl(boolean producerFlowControl) {
|
public void setProducerFlowControl(boolean producerFlowControl) {
|
||||||
this.producerFlowControl = producerFlowControl;
|
this.producerFlowControl = producerFlowControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the maxProducersToAudit
|
* @return the maxProducersToAudit
|
||||||
*/
|
*/
|
||||||
public int getMaxProducersToAudit() {
|
public int getMaxProducersToAudit() {
|
||||||
return maxProducersToAudit;
|
return maxProducersToAudit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param maxProducersToAudit the maxProducersToAudit to set
|
* @param maxProducersToAudit
|
||||||
|
* the maxProducersToAudit to set
|
||||||
*/
|
*/
|
||||||
public void setMaxProducersToAudit(int maxProducersToAudit) {
|
public void setMaxProducersToAudit(int maxProducersToAudit) {
|
||||||
this.maxProducersToAudit = maxProducersToAudit;
|
this.maxProducersToAudit = maxProducersToAudit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the maxAuditDepth
|
* @return the maxAuditDepth
|
||||||
*/
|
*/
|
||||||
public int getMaxAuditDepth() {
|
public int getMaxAuditDepth() {
|
||||||
return maxAuditDepth;
|
return maxAuditDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param maxAuditDepth the maxAuditDepth to set
|
* @param maxAuditDepth
|
||||||
|
* the maxAuditDepth to set
|
||||||
*/
|
*/
|
||||||
public void setMaxAuditDepth(int maxAuditDepth) {
|
public void setMaxAuditDepth(int maxAuditDepth) {
|
||||||
this.maxAuditDepth = maxAuditDepth;
|
this.maxAuditDepth = maxAuditDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the enableAudit
|
* @return the enableAudit
|
||||||
*/
|
*/
|
||||||
public boolean isEnableAudit() {
|
public boolean isEnableAudit() {
|
||||||
return enableAudit;
|
return enableAudit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param enableAudit the enableAudit to set
|
* @param enableAudit
|
||||||
|
* the enableAudit to set
|
||||||
*/
|
*/
|
||||||
public void setEnableAudit(boolean enableAudit) {
|
public void setEnableAudit(boolean enableAudit) {
|
||||||
this.enableAudit = enableAudit;
|
this.enableAudit = enableAudit;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addProducer(ConnectionContext context, ProducerInfo info) throws Exception{
|
public void addProducer(ConnectionContext context, ProducerInfo info) throws Exception {
|
||||||
destinationStatistics.getProducers().increment();
|
destinationStatistics.getProducers().increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeProducer(ConnectionContext context, ProducerInfo info) throws Exception{
|
public void removeProducer(ConnectionContext context, ProducerInfo info) throws Exception {
|
||||||
destinationStatistics.getProducers().decrement();
|
destinationStatistics.getProducers().decrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final MemoryUsage getMemoryUsage() {
|
public final MemoryUsage getMemoryUsage() {
|
||||||
return memoryUsage;
|
return memoryUsage;
|
||||||
}
|
}
|
||||||
|
@ -167,20 +177,19 @@ public abstract class BaseDestination implements Destination {
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final String getName() {
|
public final String getName() {
|
||||||
return getActiveMQDestination().getPhysicalName();
|
return getActiveMQDestination().getPhysicalName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final MessageStore getMessageStore() {
|
public final MessageStore getMessageStore() {
|
||||||
return store;
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean isActive() {
|
public final boolean isActive() {
|
||||||
return destinationStatistics.getConsumers().getCount() != 0 ||
|
return destinationStatistics.getConsumers().getCount() != 0
|
||||||
destinationStatistics.getProducers().getCount() != 0;
|
|| destinationStatistics.getProducers().getCount() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxPageSize() {
|
public int getMaxPageSize() {
|
||||||
return maxPageSize;
|
return maxPageSize;
|
||||||
}
|
}
|
||||||
|
@ -188,14 +197,14 @@ public abstract class BaseDestination implements Destination {
|
||||||
public void setMaxPageSize(int maxPageSize) {
|
public void setMaxPageSize(int maxPageSize) {
|
||||||
this.maxPageSize = maxPageSize;
|
this.maxPageSize = maxPageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMaxBrowsePageSize() {
|
public int getMaxBrowsePageSize() {
|
||||||
return this.maxBrowsePageSize;
|
return this.maxBrowsePageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMaxBrowsePageSize(int maxPageSize) {
|
public void setMaxBrowsePageSize(int maxPageSize) {
|
||||||
this.maxBrowsePageSize = maxPageSize;
|
this.maxBrowsePageSize = maxPageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUseCache() {
|
public boolean isUseCache() {
|
||||||
return useCache;
|
return useCache;
|
||||||
|
@ -219,8 +228,8 @@ public abstract class BaseDestination implements Destination {
|
||||||
|
|
||||||
public void setLazyDispatch(boolean lazyDispatch) {
|
public void setLazyDispatch(boolean lazyDispatch) {
|
||||||
this.lazyDispatch = lazyDispatch;
|
this.lazyDispatch = lazyDispatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long getDestinationSequenceId() {
|
protected long getDestinationSequenceId() {
|
||||||
return regionBroker.getBrokerSequenceId();
|
return regionBroker.getBrokerSequenceId();
|
||||||
}
|
}
|
||||||
|
@ -233,7 +242,8 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisoryForSlowConsumers the advisoryForSlowConsumers to set
|
* @param advisoryForSlowConsumers
|
||||||
|
* the advisoryForSlowConsumers to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisoryForSlowConsumers(boolean advisoryForSlowConsumers) {
|
public void setAdvisoryForSlowConsumers(boolean advisoryForSlowConsumers) {
|
||||||
this.advisoryForSlowConsumers = advisoryForSlowConsumers;
|
this.advisoryForSlowConsumers = advisoryForSlowConsumers;
|
||||||
|
@ -247,10 +257,10 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisoryForDiscardingMessages the advisoryForDiscardingMessages to set
|
* @param advisoryForDiscardingMessages
|
||||||
|
* the advisoryForDiscardingMessages to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisoryForDiscardingMessages(
|
public void setAdvisoryForDiscardingMessages(boolean advisoryForDiscardingMessages) {
|
||||||
boolean advisoryForDiscardingMessages) {
|
|
||||||
this.advisoryForDiscardingMessages = advisoryForDiscardingMessages;
|
this.advisoryForDiscardingMessages = advisoryForDiscardingMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +272,8 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisoryWhenFull the advisoryWhenFull to set
|
* @param advisoryWhenFull
|
||||||
|
* the advisoryWhenFull to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisoryWhenFull(boolean advisoryWhenFull) {
|
public void setAdvisoryWhenFull(boolean advisoryWhenFull) {
|
||||||
this.advisoryWhenFull = advisoryWhenFull;
|
this.advisoryWhenFull = advisoryWhenFull;
|
||||||
|
@ -276,7 +287,8 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisoryForDelivery the advisoryForDelivery to set
|
* @param advisoryForDelivery
|
||||||
|
* the advisoryForDelivery to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisoryForDelivery(boolean advisoryForDelivery) {
|
public void setAdvisoryForDelivery(boolean advisoryForDelivery) {
|
||||||
this.advisoryForDelivery = advisoryForDelivery;
|
this.advisoryForDelivery = advisoryForDelivery;
|
||||||
|
@ -290,7 +302,8 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisoryForConsumed the advisoryForConsumed to set
|
* @param advisoryForConsumed
|
||||||
|
* the advisoryForConsumed to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisoryForConsumed(boolean advisoryForConsumed) {
|
public void setAdvisoryForConsumed(boolean advisoryForConsumed) {
|
||||||
this.advisoryForConsumed = advisoryForConsumed;
|
this.advisoryForConsumed = advisoryForConsumed;
|
||||||
|
@ -304,12 +317,13 @@ public abstract class BaseDestination implements Destination {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param advisdoryForFastProducers the advisdoryForFastProducers to set
|
* @param advisdoryForFastProducers
|
||||||
|
* the advisdoryForFastProducers to set
|
||||||
*/
|
*/
|
||||||
public void setAdvisdoryForFastProducers(boolean advisdoryForFastProducers) {
|
public void setAdvisdoryForFastProducers(boolean advisdoryForFastProducers) {
|
||||||
this.advisdoryForFastProducers = advisdoryForFastProducers;
|
this.advisdoryForFastProducers = advisdoryForFastProducers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the dead letter strategy
|
* @return the dead letter strategy
|
||||||
*/
|
*/
|
||||||
|
@ -319,13 +333,16 @@ public abstract class BaseDestination implements Destination {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the dead letter strategy
|
* set the dead letter strategy
|
||||||
|
*
|
||||||
* @param deadLetterStrategy
|
* @param deadLetterStrategy
|
||||||
*/
|
*/
|
||||||
public void setDeadLetterStrategy(DeadLetterStrategy deadLetterStrategy) {
|
public void setDeadLetterStrategy(DeadLetterStrategy deadLetterStrategy) {
|
||||||
this.deadLetterStrategy = deadLetterStrategy;
|
this.deadLetterStrategy = deadLetterStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* called when message is consumed
|
* called when message is consumed
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param messageReference
|
* @param messageReference
|
||||||
*/
|
*/
|
||||||
|
@ -334,21 +351,23 @@ public abstract class BaseDestination implements Destination {
|
||||||
broker.messageConsumed(context, messageReference);
|
broker.messageConsumed(context, messageReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when message is delivered to the broker
|
* Called when message is delivered to the broker
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param messageReference
|
* @param messageReference
|
||||||
*/
|
*/
|
||||||
public void messageDelivered(ConnectionContext context, MessageReference messageReference) {
|
public void messageDelivered(ConnectionContext context, MessageReference messageReference) {
|
||||||
if(advisoryForDelivery) {
|
if (advisoryForDelivery) {
|
||||||
broker.messageDelivered(context, messageReference);
|
broker.messageDelivered(context, messageReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a message is discarded - e.g. running low on memory
|
* Called when a message is discarded - e.g. running low on memory This will happen only if the policy is enabled -
|
||||||
* This will happen only if the policy is enabled - e.g. non durable topics
|
* e.g. non durable topics
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param messageReference
|
* @param messageReference
|
||||||
*/
|
*/
|
||||||
|
@ -357,43 +376,48 @@ public abstract class BaseDestination implements Destination {
|
||||||
broker.messageDiscarded(context, messageReference);
|
broker.messageDiscarded(context, messageReference);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when there is a slow consumer
|
* Called when there is a slow consumer
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param subs
|
* @param subs
|
||||||
*/
|
*/
|
||||||
public void slowConsumer(ConnectionContext context, Subscription subs) {
|
public void slowConsumer(ConnectionContext context, Subscription subs) {
|
||||||
if(advisoryForSlowConsumers) {
|
if (advisoryForSlowConsumers) {
|
||||||
broker.slowConsumer(context, this, subs);
|
broker.slowConsumer(context, this, subs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to notify a producer is too fast
|
* Called to notify a producer is too fast
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param producerInfo
|
* @param producerInfo
|
||||||
*/
|
*/
|
||||||
public void fastProducer(ConnectionContext context,ProducerInfo producerInfo) {
|
public void fastProducer(ConnectionContext context, ProducerInfo producerInfo) {
|
||||||
if(advisdoryForFastProducers) {
|
if (advisdoryForFastProducers) {
|
||||||
broker.fastProducer(context, producerInfo);
|
broker.fastProducer(context, producerInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a Usage reaches a limit
|
* Called when a Usage reaches a limit
|
||||||
|
*
|
||||||
* @param context
|
* @param context
|
||||||
* @param usage
|
* @param usage
|
||||||
*/
|
*/
|
||||||
public void isFull(ConnectionContext context,Usage usage) {
|
public void isFull(ConnectionContext context, Usage usage) {
|
||||||
if(advisoryWhenFull) {
|
if (advisoryWhenFull) {
|
||||||
broker.isFull(context,this, usage);
|
broker.isFull(context, this, usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose(ConnectionContext context) throws IOException {
|
public void dispose(ConnectionContext context) throws IOException {
|
||||||
destinationStatistics.setParent(null);
|
if (this.store != null) {
|
||||||
|
this.store.dispose(context);
|
||||||
|
}
|
||||||
|
this.destinationStatistics.setParent(null);
|
||||||
this.memoryUsage.stop();
|
this.memoryUsage.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -475,13 +475,6 @@ public class Queue extends BaseDestination implements Task {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose(ConnectionContext context) throws IOException {
|
|
||||||
super.dispose(context);
|
|
||||||
if (store != null) {
|
|
||||||
store.removeAllMessages(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void gc(){
|
public void gc(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,6 +536,9 @@ public class Queue extends BaseDestination implements Task {
|
||||||
if (memoryUsage != null) {
|
if (memoryUsage != null) {
|
||||||
memoryUsage.stop();
|
memoryUsage.stop();
|
||||||
}
|
}
|
||||||
|
if (store!=null) {
|
||||||
|
store.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
|
|
|
@ -449,13 +449,7 @@ public class Topic extends BaseDestination implements Task{
|
||||||
messageConsumed(context, node);
|
messageConsumed(context, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose(ConnectionContext context) throws IOException {
|
|
||||||
super.dispose(context);
|
|
||||||
if (topicStore != null) {
|
|
||||||
topicStore.removeAllMessages(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void gc() {
|
public void gc() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,6 +473,9 @@ public class Topic extends BaseDestination implements Task{
|
||||||
if (memoryUsage != null) {
|
if (memoryUsage != null) {
|
||||||
memoryUsage.stop();
|
memoryUsage.stop();
|
||||||
}
|
}
|
||||||
|
if(this.topicStore != null) {
|
||||||
|
this.topicStore.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Message[] browse() {
|
public Message[] browse() {
|
||||||
|
|
|
@ -283,4 +283,9 @@ public interface MapContainer<K, V> extends Map<K, V> {
|
||||||
* @return the Index MBean
|
* @return the Index MBean
|
||||||
*/
|
*/
|
||||||
IndexMBean getIndexMBean();
|
IndexMBean getIndexMBean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up all state associated with this container.
|
||||||
|
*/
|
||||||
|
void delete();
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,6 +142,16 @@ public final class MapContainerImpl extends BaseContainerImpl implements MapCont
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void delete() {
|
||||||
|
unload();
|
||||||
|
try {
|
||||||
|
index.delete();
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.warn("Failed to unload the index", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized void setKeyMarshaller(Marshaller keyMarshaller) {
|
public synchronized void setKeyMarshaller(Marshaller keyMarshaller) {
|
||||||
checkClosed();
|
checkClosed();
|
||||||
this.keyMarshaller = keyMarshaller;
|
this.keyMarshaller = keyMarshaller;
|
||||||
|
@ -578,7 +588,6 @@ public final class MapContainerImpl extends BaseContainerImpl implements MapCont
|
||||||
public IndexMBean getIndexMBean() {
|
public IndexMBean getIndexMBean() {
|
||||||
return (IndexMBean) index;
|
return (IndexMBean) index;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndexMaxBinSize() {
|
public int getIndexMaxBinSize() {
|
||||||
return indexMaxBinSize;
|
return indexMaxBinSize;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,4 +96,11 @@ public interface Index {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int getSize();
|
int getSize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete all state associated with the index
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
void delete() throws IOException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index implementation using a HashMap
|
* Index implementation using a HashMap
|
||||||
*
|
*
|
||||||
* @version $Revision: 1.2 $
|
* @version $Revision: 1.2 $
|
||||||
*/
|
*/
|
||||||
public class VMIndex implements Index, IndexMBean {
|
public class VMIndex implements Index, IndexMBean {
|
||||||
|
@ -41,7 +41,7 @@ public class VMIndex implements Index, IndexMBean {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @see org.apache.activemq.kaha.impl.index.Index#clear()
|
* @see org.apache.activemq.kaha.impl.index.Index#clear()
|
||||||
*/
|
*/
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
@ -122,9 +122,13 @@ public class VMIndex implements Index, IndexMBean {
|
||||||
map.clear();
|
map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void delete() throws IOException {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
public void setKeyMarshaller(Marshaller marshaller) {
|
public void setKeyMarshaller(Marshaller marshaller) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSize() {
|
public int getSize() {
|
||||||
return map.size();
|
return map.size();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.store;
|
||||||
|
|
||||||
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
|
import org.apache.activemq.broker.ConnectionContext;
|
||||||
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
|
|
||||||
|
abstract public class AbstractMessageStore implements MessageStore {
|
||||||
|
protected final ActiveMQDestination destination;
|
||||||
|
|
||||||
|
public AbstractMessageStore(ActiveMQDestination destination) {
|
||||||
|
this.destination = destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose(ConnectionContext context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveMQDestination getDestination() {
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMemoryUsage(MemoryUsage memoryUsage) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -109,4 +109,5 @@ public interface MessageStore extends Service {
|
||||||
|
|
||||||
void recoverNextMessages(int maxReturned, MessageRecoveryListener listener) throws Exception;
|
void recoverNextMessages(int maxReturned, MessageRecoveryListener listener) throws Exception;
|
||||||
|
|
||||||
|
void dispose(ConnectionContext context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,10 @@ public class ProxyMessageStore implements MessageStore {
|
||||||
delegate.stop();
|
delegate.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispose(ConnectionContext context) {
|
||||||
|
delegate.dispose(context);
|
||||||
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
public ActiveMQDestination getDestination() {
|
||||||
return delegate.getDestination();
|
return delegate.getDestination();
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,6 +126,10 @@ public class ProxyTopicMessageStore implements TopicMessageStore {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispose(ConnectionContext context) {
|
||||||
|
delegate.dispose(context);
|
||||||
|
}
|
||||||
|
|
||||||
public void resetBatching() {
|
public void resetBatching() {
|
||||||
delegate.resetBatching();
|
delegate.resetBatching();
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ import java.util.Map.Entry;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
|
|
||||||
import org.apache.activemq.broker.ConnectionContext;
|
import org.apache.activemq.broker.ConnectionContext;
|
||||||
import org.apache.activemq.command.ActiveMQDestination;
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
import org.apache.activemq.command.DataStructure;
|
import org.apache.activemq.command.DataStructure;
|
||||||
|
@ -40,8 +39,8 @@ import org.apache.activemq.command.MessageAck;
|
||||||
import org.apache.activemq.command.MessageId;
|
import org.apache.activemq.command.MessageId;
|
||||||
import org.apache.activemq.filter.NonCachedMessageEvaluationContext;
|
import org.apache.activemq.filter.NonCachedMessageEvaluationContext;
|
||||||
import org.apache.activemq.kaha.impl.async.Location;
|
import org.apache.activemq.kaha.impl.async.Location;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.MessageStore;
|
|
||||||
import org.apache.activemq.store.PersistenceAdapter;
|
import org.apache.activemq.store.PersistenceAdapter;
|
||||||
import org.apache.activemq.store.ReferenceStore;
|
import org.apache.activemq.store.ReferenceStore;
|
||||||
import org.apache.activemq.store.ReferenceStore.ReferenceData;
|
import org.apache.activemq.store.ReferenceStore.ReferenceData;
|
||||||
|
@ -59,21 +58,17 @@ import org.apache.commons.logging.LogFactory;
|
||||||
*
|
*
|
||||||
* @version $Revision: 1.14 $
|
* @version $Revision: 1.14 $
|
||||||
*/
|
*/
|
||||||
public class AMQMessageStore implements MessageStore {
|
public class AMQMessageStore extends AbstractMessageStore {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(AMQMessageStore.class);
|
private static final Log LOG = LogFactory.getLog(AMQMessageStore.class);
|
||||||
|
|
||||||
protected final AMQPersistenceAdapter peristenceAdapter;
|
protected final AMQPersistenceAdapter peristenceAdapter;
|
||||||
protected final AMQTransactionStore transactionStore;
|
protected final AMQTransactionStore transactionStore;
|
||||||
protected final ReferenceStore referenceStore;
|
protected final ReferenceStore referenceStore;
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final TransactionTemplate transactionTemplate;
|
protected final TransactionTemplate transactionTemplate;
|
||||||
protected Location lastLocation;
|
protected Location lastLocation;
|
||||||
protected Location lastWrittenLocation;
|
protected Location lastWrittenLocation;
|
||||||
protected Set<Location> inFlightTxLocations = new HashSet<Location>();
|
protected Set<Location> inFlightTxLocations = new HashSet<Location>();
|
||||||
protected final TaskRunner asyncWriteTask;
|
protected final TaskRunner asyncWriteTask;
|
||||||
protected CountDownLatch flushLatch;
|
protected CountDownLatch flushLatch;
|
||||||
|
|
||||||
private Map<MessageId, ReferenceData> messages = new LinkedHashMap<MessageId, ReferenceData>();
|
private Map<MessageId, ReferenceData> messages = new LinkedHashMap<MessageId, ReferenceData>();
|
||||||
private List<MessageAck> messageAcks = new ArrayList<MessageAck>();
|
private List<MessageAck> messageAcks = new ArrayList<MessageAck>();
|
||||||
/** A MessageStore that we can use to retrieve messages quickly. */
|
/** A MessageStore that we can use to retrieve messages quickly. */
|
||||||
|
@ -82,15 +77,15 @@ public class AMQMessageStore implements MessageStore {
|
||||||
private final AtomicReference<Location> mark = new AtomicReference<Location>();
|
private final AtomicReference<Location> mark = new AtomicReference<Location>();
|
||||||
protected final Lock lock;
|
protected final Lock lock;
|
||||||
|
|
||||||
public AMQMessageStore(AMQPersistenceAdapter adapter,ReferenceStore referenceStore, ActiveMQDestination destination) {
|
public AMQMessageStore(AMQPersistenceAdapter adapter, ReferenceStore referenceStore, ActiveMQDestination destination) {
|
||||||
|
super(destination);
|
||||||
this.peristenceAdapter = adapter;
|
this.peristenceAdapter = adapter;
|
||||||
this.lock=referenceStore.getStoreLock();
|
this.lock = referenceStore.getStoreLock();
|
||||||
this.transactionStore = adapter.getTransactionStore();
|
this.transactionStore = adapter.getTransactionStore();
|
||||||
this.referenceStore = referenceStore;
|
this.referenceStore = referenceStore;
|
||||||
this.destination = destination;
|
this.transactionTemplate = new TransactionTemplate(adapter, new ConnectionContext(
|
||||||
this.transactionTemplate = new TransactionTemplate(adapter, new ConnectionContext(new NonCachedMessageEvaluationContext()));
|
new NonCachedMessageEvaluationContext()));
|
||||||
asyncWriteTask = adapter.getTaskRunnerFactory().createTaskRunner(new Task() {
|
asyncWriteTask = adapter.getTaskRunnerFactory().createTaskRunner(new Task() {
|
||||||
|
|
||||||
public boolean iterate() {
|
public boolean iterate() {
|
||||||
asyncWrite();
|
asyncWrite();
|
||||||
return false;
|
return false;
|
||||||
|
@ -103,8 +98,8 @@ public class AMQMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Not synchronize since the Journal has better throughput if you increase
|
* Not synchronize since the Journal has better throughput if you increase the number of concurrent writes that it
|
||||||
* the number of concurrent writes that it is doing.
|
* is doing.
|
||||||
*/
|
*/
|
||||||
public final void addMessage(ConnectionContext context, final Message message) throws IOException {
|
public final void addMessage(ConnectionContext context, final Message message) throws IOException {
|
||||||
final MessageId id = message.getMessageId();
|
final MessageId id = message.getMessageId();
|
||||||
|
@ -122,12 +117,11 @@ public class AMQMessageStore implements MessageStore {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.add(location);
|
inFlightTxLocations.add(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
transactionStore.addMessage(this, message, location);
|
transactionStore.addMessage(this, message, location);
|
||||||
context.getTransaction().addSynchronization(new Synchronization() {
|
context.getTransaction().addSynchronization(new Synchronization() {
|
||||||
|
|
||||||
public void afterCommit() throws Exception {
|
public void afterCommit() throws Exception {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Transacted message add commit for: " + id + ", at: " + location);
|
LOG.debug("Transacted message add commit for: " + id + ", at: " + location);
|
||||||
|
@ -135,7 +129,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.remove(location);
|
inFlightTxLocations.remove(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
addMessage(message, location);
|
addMessage(message, location);
|
||||||
|
@ -148,7 +142,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.remove(location);
|
inFlightTxLocations.remove(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,15 +155,14 @@ public class AMQMessageStore implements MessageStore {
|
||||||
data.setExpiration(message.getExpiration());
|
data.setExpiration(message.getExpiration());
|
||||||
data.setFileId(location.getDataFileId());
|
data.setFileId(location.getDataFileId());
|
||||||
data.setOffset(location.getOffset());
|
data.setOffset(location.getOffset());
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
lastLocation = location;
|
lastLocation = location;
|
||||||
messages.put(message.getMessageId(), data);
|
messages.put(message.getMessageId(), data);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (messages.size() > this.peristenceAdapter
|
if (messages.size() > this.peristenceAdapter.getMaxCheckpointMessageAddSize()) {
|
||||||
.getMaxCheckpointMessageAddSize()) {
|
|
||||||
flush();
|
flush();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -194,7 +187,8 @@ public class AMQMessageStore implements MessageStore {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOG.warn("Could not replay add for message '" + id + "'. Message may have already been added. reason: " + e, e);
|
LOG.warn("Could not replay add for message '" + id + "'. Message may have already been added. reason: "
|
||||||
|
+ e, e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -210,7 +204,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Journalled message remove for: " + ack.getLastMessageId() + ", at: " + location);
|
LOG.debug("Journalled message remove for: " + ack.getLastMessageId() + ", at: " + location);
|
||||||
}
|
}
|
||||||
removeMessage(ack,location);
|
removeMessage(ack, location);
|
||||||
} else {
|
} else {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Journalled transacted message remove for: " + ack.getLastMessageId() + ", at: " + location);
|
LOG.debug("Journalled transacted message remove for: " + ack.getLastMessageId() + ", at: " + location);
|
||||||
|
@ -218,33 +212,34 @@ public class AMQMessageStore implements MessageStore {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.add(location);
|
inFlightTxLocations.add(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
transactionStore.removeMessage(this, ack, location);
|
transactionStore.removeMessage(this, ack, location);
|
||||||
context.getTransaction().addSynchronization(new Synchronization() {
|
context.getTransaction().addSynchronization(new Synchronization() {
|
||||||
|
|
||||||
public void afterCommit() throws Exception {
|
public void afterCommit() throws Exception {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Transacted message remove commit for: " + ack.getLastMessageId() + ", at: " + location);
|
LOG.debug("Transacted message remove commit for: " + ack.getLastMessageId() + ", at: "
|
||||||
|
+ location);
|
||||||
}
|
}
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.remove(location);
|
inFlightTxLocations.remove(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
removeMessage(ack,location);
|
removeMessage(ack, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void afterRollback() throws Exception {
|
public void afterRollback() throws Exception {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
LOG.debug("Transacted message remove rollback for: " + ack.getLastMessageId() + ", at: " + location);
|
LOG.debug("Transacted message remove rollback for: " + ack.getLastMessageId() + ", at: "
|
||||||
|
+ location);
|
||||||
}
|
}
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
inFlightTxLocations.remove(location);
|
inFlightTxLocations.remove(location);
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,7 +250,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
final void removeMessage(final MessageAck ack, final Location location) throws InterruptedIOException {
|
final void removeMessage(final MessageAck ack, final Location location) throws InterruptedIOException {
|
||||||
ReferenceData data;
|
ReferenceData data;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try{
|
try {
|
||||||
lastLocation = location;
|
lastLocation = location;
|
||||||
MessageId id = ack.getLastMessageId();
|
MessageId id = ack.getLastMessageId();
|
||||||
data = messages.remove(id);
|
data = messages.remove(id);
|
||||||
|
@ -265,13 +260,12 @@ public class AMQMessageStore implements MessageStore {
|
||||||
// message never got written so datafileReference will still exist
|
// message never got written so datafileReference will still exist
|
||||||
AMQMessageStore.this.peristenceAdapter.removeInProgressDataFile(AMQMessageStore.this, data.getFileId());
|
AMQMessageStore.this.peristenceAdapter.removeInProgressDataFile(AMQMessageStore.this, data.getFileId());
|
||||||
}
|
}
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (messageAcks.size() > this.peristenceAdapter.getMaxCheckpointMessageAddSize()) {
|
if (messageAcks.size() > this.peristenceAdapter.getMaxCheckpointMessageAddSize()) {
|
||||||
flush();
|
flush();
|
||||||
}
|
} else if (data == null) {
|
||||||
else if (data == null) {
|
|
||||||
try {
|
try {
|
||||||
asyncWriteTask.wakeup();
|
asyncWriteTask.wakeup();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
@ -279,7 +273,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean replayRemoveMessage(ConnectionContext context, MessageAck messageAck) {
|
public boolean replayRemoveMessage(ConnectionContext context, MessageAck messageAck) {
|
||||||
try {
|
try {
|
||||||
// Only remove the message if it has not already been removed.
|
// Only remove the message if it has not already been removed.
|
||||||
|
@ -289,7 +283,8 @@ public class AMQMessageStore implements MessageStore {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOG.warn("Could not replay acknowledge for message '" + messageAck.getLastMessageId() + "'. Message may have already been acknowledged. reason: " + e);
|
LOG.warn("Could not replay acknowledge for message '" + messageAck.getLastMessageId()
|
||||||
|
+ "'. Message may have already been acknowledged. reason: " + e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +308,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
flushLatch = new CountDownLatch(1);
|
flushLatch = new CountDownLatch(1);
|
||||||
}
|
}
|
||||||
countDown = flushLatch;
|
countDown = flushLatch;
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -338,7 +333,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
try {
|
try {
|
||||||
countDown = flushLatch;
|
countDown = flushLatch;
|
||||||
flushLatch = null;
|
flushLatch = null;
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
mark.set(doAsyncWrite());
|
mark.set(doAsyncWrite());
|
||||||
|
@ -368,14 +363,14 @@ public class AMQMessageStore implements MessageStore {
|
||||||
this.messages = new LinkedHashMap<MessageId, ReferenceData>();
|
this.messages = new LinkedHashMap<MessageId, ReferenceData>();
|
||||||
this.messageAcks = new ArrayList<MessageAck>();
|
this.messageAcks = new ArrayList<MessageAck>();
|
||||||
lastLocation = this.lastLocation;
|
lastLocation = this.lastLocation;
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("Doing batch update... adding: " + cpAddedMessageIds.size() + " removing: " + cpRemovedMessageLocations.size() + " ");
|
LOG.debug("Doing batch update... adding: " + cpAddedMessageIds.size() + " removing: "
|
||||||
|
+ cpRemovedMessageLocations.size() + " ");
|
||||||
}
|
}
|
||||||
transactionTemplate.run(new Callback() {
|
transactionTemplate.run(new Callback() {
|
||||||
|
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
int size = 0;
|
int size = 0;
|
||||||
PersistenceAdapter persitanceAdapter = transactionTemplate.getPersistenceAdapter();
|
PersistenceAdapter persitanceAdapter = transactionTemplate.getPersistenceAdapter();
|
||||||
|
@ -386,7 +381,8 @@ public class AMQMessageStore implements MessageStore {
|
||||||
Entry<MessageId, ReferenceData> entry = iterator.next();
|
Entry<MessageId, ReferenceData> entry = iterator.next();
|
||||||
try {
|
try {
|
||||||
referenceStore.addMessageReference(context, entry.getKey(), entry.getValue());
|
referenceStore.addMessageReference(context, entry.getKey(), entry.getValue());
|
||||||
AMQMessageStore.this.peristenceAdapter.removeInProgressDataFile(AMQMessageStore.this,entry.getValue().getFileId());
|
AMQMessageStore.this.peristenceAdapter.removeInProgressDataFile(AMQMessageStore.this, entry
|
||||||
|
.getValue().getFileId());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
LOG.warn("Message could not be added to long term store: " + e.getMessage(), e);
|
LOG.warn("Message could not be added to long term store: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
@ -415,7 +411,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
try {
|
try {
|
||||||
cpAddedMessageIds = null;
|
cpAddedMessageIds = null;
|
||||||
lastWrittenLocation = lastLocation;
|
lastWrittenLocation = lastLocation;
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (cpActiveJournalLocations.size() > 0) {
|
if (cpActiveJournalLocations.size() > 0) {
|
||||||
|
@ -436,14 +432,13 @@ public class AMQMessageStore implements MessageStore {
|
||||||
try {
|
try {
|
||||||
return (Message) rc;
|
return (Message) rc;
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
throw new IOException("Could not read message " + identity
|
throw new IOException("Could not read message " + identity + " at location " + location
|
||||||
+ " at location " + location
|
|
||||||
+ ", expected a message, but got: " + rc);
|
+ ", expected a message, but got: " + rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Location getLocation(MessageId messageId) throws IOException {
|
protected Location getLocation(MessageId messageId) throws IOException {
|
||||||
ReferenceData data = null;
|
ReferenceData data = null;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
@ -453,7 +448,7 @@ public class AMQMessageStore implements MessageStore {
|
||||||
if (data == null && cpAddedMessageIds != null) {
|
if (data == null && cpAddedMessageIds != null) {
|
||||||
data = cpAddedMessageIds.get(messageId);
|
data = cpAddedMessageIds.get(messageId);
|
||||||
}
|
}
|
||||||
}finally {
|
} finally {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
}
|
}
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
|
@ -469,16 +464,15 @@ public class AMQMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replays the referenceStore first as those messages are the oldest ones,
|
* Replays the referenceStore first as those messages are the oldest ones, then messages are replayed from the
|
||||||
* then messages are replayed from the transaction log and then the cache is
|
* transaction log and then the cache is updated.
|
||||||
* updated.
|
|
||||||
*
|
*
|
||||||
* @param listener
|
* @param listener
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public void recover(final MessageRecoveryListener listener) throws Exception {
|
public void recover(final MessageRecoveryListener listener) throws Exception {
|
||||||
flush();
|
flush();
|
||||||
referenceStore.recover(new RecoveryListenerAdapter(this, listener));
|
referenceStore.recover(new RecoveryListenerAdapter(this, listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws Exception {
|
public void start() throws Exception {
|
||||||
|
@ -506,11 +500,8 @@ public class AMQMessageStore implements MessageStore {
|
||||||
referenceStore.removeAllMessages(context);
|
referenceStore.removeAllMessages(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
public void addMessageReference(ConnectionContext context, MessageId messageId, long expirationTime,
|
||||||
return destination;
|
String messageRef) throws IOException {
|
||||||
}
|
|
||||||
|
|
||||||
public void addMessageReference(ConnectionContext context, MessageId messageId, long expirationTime, String messageRef) throws IOException {
|
|
||||||
throw new IOException("The journal does not support message references.");
|
throw new IOException("The journal does not support message references.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,9 +534,10 @@ public class AMQMessageStore implements MessageStore {
|
||||||
location.setOffset(data.getOffset());
|
location.setOffset(data.getOffset());
|
||||||
DataStructure rc = peristenceAdapter.readCommand(location);
|
DataStructure rc = peristenceAdapter.readCommand(location);
|
||||||
try {
|
try {
|
||||||
return (Message)rc;
|
return (Message) rc;
|
||||||
} catch (ClassCastException e) {
|
} catch (ClassCastException e) {
|
||||||
throw new IOException("Could not read message at location " + location + ", expected a message, but got: " + rc);
|
throw new IOException("Could not read message at location " + location + ", expected a message, but got: "
|
||||||
|
+ rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,4 +548,14 @@ public class AMQMessageStore implements MessageStore {
|
||||||
public Location getMark() {
|
public Location getMark() {
|
||||||
return mark.get();
|
return mark.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispose(ConnectionContext context) {
|
||||||
|
try {
|
||||||
|
flush();
|
||||||
|
} catch (InterruptedIOException e) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
referenceStore.dispose(context);
|
||||||
|
super.dispose(context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@ import org.apache.activemq.command.MessageAck;
|
||||||
import org.apache.activemq.command.MessageId;
|
import org.apache.activemq.command.MessageId;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.MessageStore;
|
import org.apache.activemq.store.MessageStore;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.usage.SystemUsage;
|
|
||||||
import org.apache.activemq.util.ByteSequence;
|
import org.apache.activemq.util.ByteSequence;
|
||||||
import org.apache.activemq.util.ByteSequenceData;
|
import org.apache.activemq.util.ByteSequenceData;
|
||||||
import org.apache.activemq.util.IOExceptionSupport;
|
import org.apache.activemq.util.IOExceptionSupport;
|
||||||
|
@ -37,19 +37,18 @@ import org.apache.activemq.wireformat.WireFormat;
|
||||||
/**
|
/**
|
||||||
* @version $Revision: 1.10 $
|
* @version $Revision: 1.10 $
|
||||||
*/
|
*/
|
||||||
public class JDBCMessageStore implements MessageStore {
|
public class JDBCMessageStore extends AbstractMessageStore {
|
||||||
|
|
||||||
protected final WireFormat wireFormat;
|
protected final WireFormat wireFormat;
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final JDBCAdapter adapter;
|
protected final JDBCAdapter adapter;
|
||||||
protected final JDBCPersistenceAdapter persistenceAdapter;
|
protected final JDBCPersistenceAdapter persistenceAdapter;
|
||||||
protected AtomicLong lastMessageId = new AtomicLong(-1);
|
protected AtomicLong lastMessageId = new AtomicLong(-1);
|
||||||
|
|
||||||
public JDBCMessageStore(JDBCPersistenceAdapter persistenceAdapter, JDBCAdapter adapter, WireFormat wireFormat, ActiveMQDestination destination) {
|
public JDBCMessageStore(JDBCPersistenceAdapter persistenceAdapter, JDBCAdapter adapter, WireFormat wireFormat, ActiveMQDestination destination) {
|
||||||
|
super(destination);
|
||||||
this.persistenceAdapter = persistenceAdapter;
|
this.persistenceAdapter = persistenceAdapter;
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
this.wireFormat = wireFormat;
|
this.wireFormat = wireFormat;
|
||||||
this.destination = destination;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMessage(ConnectionContext context, Message message) throws IOException {
|
public void addMessage(ConnectionContext context, Message message) throws IOException {
|
||||||
|
@ -169,12 +168,6 @@ public class JDBCMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.apache.activemq.store.MessageStore#removeAllMessages(ConnectionContext)
|
* @see org.apache.activemq.store.MessageStore#removeAllMessages(ConnectionContext)
|
||||||
*/
|
*/
|
||||||
|
@ -191,15 +184,6 @@ public class JDBCMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMemoryUsage(MemoryUsage memoryUsage) {
|
|
||||||
//can ignore as messages aren't buffered
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getMessageCount() throws IOException {
|
public int getMessageCount() throws IOException {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
TransactionContext c = persistenceAdapter.getTransactionContext();
|
TransactionContext c = persistenceAdapter.getTransactionContext();
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.activemq.filter.NonCachedMessageEvaluationContext;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.MessageStore;
|
import org.apache.activemq.store.MessageStore;
|
||||||
import org.apache.activemq.store.PersistenceAdapter;
|
import org.apache.activemq.store.PersistenceAdapter;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.transaction.Synchronization;
|
import org.apache.activemq.transaction.Synchronization;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.usage.SystemUsage;
|
import org.apache.activemq.usage.SystemUsage;
|
||||||
|
@ -50,14 +51,13 @@ import org.apache.commons.logging.LogFactory;
|
||||||
*
|
*
|
||||||
* @version $Revision: 1.14 $
|
* @version $Revision: 1.14 $
|
||||||
*/
|
*/
|
||||||
public class JournalMessageStore implements MessageStore {
|
public class JournalMessageStore extends AbstractMessageStore {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(JournalMessageStore.class);
|
private static final Log LOG = LogFactory.getLog(JournalMessageStore.class);
|
||||||
|
|
||||||
protected final JournalPersistenceAdapter peristenceAdapter;
|
protected final JournalPersistenceAdapter peristenceAdapter;
|
||||||
protected final JournalTransactionStore transactionStore;
|
protected final JournalTransactionStore transactionStore;
|
||||||
protected final MessageStore longTermStore;
|
protected final MessageStore longTermStore;
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final TransactionTemplate transactionTemplate;
|
protected final TransactionTemplate transactionTemplate;
|
||||||
protected RecordLocation lastLocation;
|
protected RecordLocation lastLocation;
|
||||||
protected Set<RecordLocation> inFlightTxLocations = new HashSet<RecordLocation>();
|
protected Set<RecordLocation> inFlightTxLocations = new HashSet<RecordLocation>();
|
||||||
|
@ -72,10 +72,10 @@ public class JournalMessageStore implements MessageStore {
|
||||||
private MemoryUsage memoryUsage;
|
private MemoryUsage memoryUsage;
|
||||||
|
|
||||||
public JournalMessageStore(JournalPersistenceAdapter adapter, MessageStore checkpointStore, ActiveMQDestination destination) {
|
public JournalMessageStore(JournalPersistenceAdapter adapter, MessageStore checkpointStore, ActiveMQDestination destination) {
|
||||||
|
super(destination);
|
||||||
this.peristenceAdapter = adapter;
|
this.peristenceAdapter = adapter;
|
||||||
this.transactionStore = adapter.getTransactionStore();
|
this.transactionStore = adapter.getTransactionStore();
|
||||||
this.longTermStore = checkpointStore;
|
this.longTermStore = checkpointStore;
|
||||||
this.destination = destination;
|
|
||||||
this.transactionTemplate = new TransactionTemplate(adapter, new ConnectionContext(new NonCachedMessageEvaluationContext()));
|
this.transactionTemplate = new TransactionTemplate(adapter, new ConnectionContext(new NonCachedMessageEvaluationContext()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,10 +382,6 @@ public class JournalMessageStore implements MessageStore {
|
||||||
longTermStore.removeAllMessages(context);
|
longTermStore.removeAllMessages(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMessageReference(ConnectionContext context, MessageId messageId, long expirationTime, String messageRef) throws IOException {
|
public void addMessageReference(ConnectionContext context, MessageId messageId, long expirationTime, String messageRef) throws IOException {
|
||||||
throw new IOException("The journal does not support message references.");
|
throw new IOException("The journal does not support message references.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.activemq.kaha.MapContainer;
|
||||||
import org.apache.activemq.kaha.StoreEntry;
|
import org.apache.activemq.kaha.StoreEntry;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.MessageStore;
|
import org.apache.activemq.store.MessageStore;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.usage.SystemUsage;
|
import org.apache.activemq.usage.SystemUsage;
|
||||||
|
|
||||||
|
@ -35,16 +36,15 @@ import org.apache.activemq.usage.SystemUsage;
|
||||||
*
|
*
|
||||||
* @version $Revision: 1.7 $
|
* @version $Revision: 1.7 $
|
||||||
*/
|
*/
|
||||||
public class KahaMessageStore implements MessageStore {
|
public class KahaMessageStore extends AbstractMessageStore {
|
||||||
|
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final MapContainer<MessageId, Message> messageContainer;
|
protected final MapContainer<MessageId, Message> messageContainer;
|
||||||
protected StoreEntry batchEntry;
|
protected StoreEntry batchEntry;
|
||||||
|
|
||||||
public KahaMessageStore(MapContainer<MessageId, Message> container, ActiveMQDestination destination)
|
public KahaMessageStore(MapContainer<MessageId, Message> container, ActiveMQDestination destination)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
super(destination);
|
||||||
this.messageContainer = container;
|
this.messageContainer = container;
|
||||||
this.destination = destination;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MessageId getMessageId(Object object) {
|
protected MessageId getMessageId(Object object) {
|
||||||
|
@ -101,27 +101,14 @@ public class KahaMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void removeAllMessages(ConnectionContext context) throws IOException {
|
public synchronized void removeAllMessages(ConnectionContext context) throws IOException {
|
||||||
messageContainer.clear();
|
messageContainer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void delete() {
|
public synchronized void delete() {
|
||||||
messageContainer.clear();
|
messageContainer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryUsage(MemoryUsage memoryUsage) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the number of messages held by this destination
|
* @return the number of messages held by this destination
|
||||||
* @see org.apache.activemq.store.MessageStore#getMessageCount()
|
* @see org.apache.activemq.store.MessageStore#getMessageCount()
|
||||||
|
|
|
@ -31,15 +31,15 @@ import org.apache.activemq.kaha.MapContainer;
|
||||||
import org.apache.activemq.kaha.StoreEntry;
|
import org.apache.activemq.kaha.StoreEntry;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.ReferenceStore;
|
import org.apache.activemq.store.ReferenceStore;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author rajdavies
|
* @author rajdavies
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class KahaReferenceStore implements ReferenceStore {
|
public class KahaReferenceStore extends AbstractMessageStore implements ReferenceStore {
|
||||||
|
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final MapContainer<MessageId, ReferenceRecord> messageContainer;
|
protected final MapContainer<MessageId, ReferenceRecord> messageContainer;
|
||||||
protected KahaReferenceStoreAdapter adapter;
|
protected KahaReferenceStoreAdapter adapter;
|
||||||
private StoreEntry batchEntry;
|
private StoreEntry batchEntry;
|
||||||
|
@ -48,19 +48,19 @@ public class KahaReferenceStore implements ReferenceStore {
|
||||||
|
|
||||||
public KahaReferenceStore(KahaReferenceStoreAdapter adapter, MapContainer<MessageId, ReferenceRecord> container,
|
public KahaReferenceStore(KahaReferenceStoreAdapter adapter, MapContainer<MessageId, ReferenceRecord> container,
|
||||||
ActiveMQDestination destination) throws IOException {
|
ActiveMQDestination destination) throws IOException {
|
||||||
|
super(destination);
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
this.messageContainer = container;
|
this.messageContainer = container;
|
||||||
this.destination = destination;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Lock getStoreLock() {
|
public Lock getStoreLock() {
|
||||||
return lock;
|
return lock;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
public void dispose(ConnectionContext context) {
|
||||||
}
|
super.dispose(context);
|
||||||
|
this.messageContainer.delete();
|
||||||
public void stop() {
|
this.adapter.removeReferenceStore(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MessageId getMessageId(Object object) {
|
protected MessageId getMessageId(Object object) {
|
||||||
|
@ -204,10 +204,6 @@ public class KahaReferenceStore implements ReferenceStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
@ -231,9 +227,6 @@ public class KahaReferenceStore implements ReferenceStore {
|
||||||
return messageContainer.size();
|
return messageContainer.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMemoryUsage(MemoryUsage memoryUsage) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSupportForCursors() {
|
public boolean isSupportForCursors() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.apache.activemq.command.ActiveMQTopic;
|
||||||
import org.apache.activemq.command.MessageId;
|
import org.apache.activemq.command.MessageId;
|
||||||
import org.apache.activemq.command.SubscriptionInfo;
|
import org.apache.activemq.command.SubscriptionInfo;
|
||||||
import org.apache.activemq.command.TransactionId;
|
import org.apache.activemq.command.TransactionId;
|
||||||
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
import org.apache.activemq.kaha.CommandMarshaller;
|
import org.apache.activemq.kaha.CommandMarshaller;
|
||||||
import org.apache.activemq.kaha.ListContainer;
|
import org.apache.activemq.kaha.ListContainer;
|
||||||
import org.apache.activemq.kaha.MapContainer;
|
import org.apache.activemq.kaha.MapContainer;
|
||||||
|
@ -179,6 +180,16 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeReferenceStore(KahaReferenceStore store) {
|
||||||
|
ActiveMQDestination destination = store.getDestination();
|
||||||
|
if (destination.isQueue()) {
|
||||||
|
queues.remove(destination);
|
||||||
|
} else {
|
||||||
|
topics.remove(destination);
|
||||||
|
}
|
||||||
|
messageStores.remove(destination);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
public void buildReferenceFileIdsInUse() throws IOException {
|
public void buildReferenceFileIdsInUse() throws IOException {
|
||||||
recordReferences = new HashMap<Integer, AtomicInteger>();
|
recordReferences = new HashMap<Integer, AtomicInteger>();
|
||||||
|
@ -239,7 +250,7 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @see org.apache.activemq.store.ReferenceStoreAdapter#clearMessages()
|
* @see org.apache.activemq.store.ReferenceStoreAdapter#clearMessages()
|
||||||
*/
|
*/
|
||||||
|
@ -250,13 +261,13 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @see org.apache.activemq.store.ReferenceStoreAdapter#recoverState()
|
* @see org.apache.activemq.store.ReferenceStoreAdapter#recoverState()
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void recoverState() throws IOException {
|
public void recoverState() throws IOException {
|
||||||
Set<SubscriptionInfo> set = new HashSet<SubscriptionInfo>(this.durableSubscribers);
|
Set<SubscriptionInfo> set = new HashSet<SubscriptionInfo>(this.durableSubscribers);
|
||||||
for (SubscriptionInfo info:set) {
|
for (SubscriptionInfo info:set) {
|
||||||
LOG.info("Recovering subscriber state for durable subscriber: " + info);
|
LOG.info("Recovering subscriber state for durable subscriber: " + info);
|
||||||
TopicReferenceStore ts = createTopicReferenceStore((ActiveMQTopic)info.getDestination());
|
TopicReferenceStore ts = createTopicReferenceStore((ActiveMQTopic)info.getDestination());
|
||||||
|
@ -312,7 +323,7 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
StoreFactory.delete(stateDirectory);
|
StoreFactory.delete(stateDirectory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPersistentIndex() {
|
public boolean isPersistentIndex() {
|
||||||
return persistentIndex;
|
return persistentIndex;
|
||||||
}
|
}
|
||||||
|
@ -363,7 +374,7 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
public void setIndexPageSize(int indexPageSize) {
|
public void setIndexPageSize(int indexPageSize) {
|
||||||
this.indexPageSize = indexPageSize;
|
this.indexPageSize = indexPageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getIndexMaxBinSize() {
|
public int getIndexMaxBinSize() {
|
||||||
return indexMaxBinSize;
|
return indexMaxBinSize;
|
||||||
}
|
}
|
||||||
|
@ -371,7 +382,7 @@ public class KahaReferenceStoreAdapter extends KahaPersistenceAdapter implements
|
||||||
public void setIndexMaxBinSize(int maxBinSize) {
|
public void setIndexMaxBinSize(int maxBinSize) {
|
||||||
this.indexMaxBinSize = maxBinSize;
|
this.indexMaxBinSize = maxBinSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the loadFactor
|
* @return the loadFactor
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class KahaTopicReferenceStore extends KahaReferenceStore implements Topic
|
||||||
|
|
||||||
protected ListContainer<TopicSubAck> ackContainer;
|
protected ListContainer<TopicSubAck> ackContainer;
|
||||||
protected Map<String, TopicSubContainer> subscriberMessages = new ConcurrentHashMap<String, TopicSubContainer>();
|
protected Map<String, TopicSubContainer> subscriberMessages = new ConcurrentHashMap<String, TopicSubContainer>();
|
||||||
private Map<String, SubscriptionInfo> subscriberContainer;
|
private MapContainer<String, SubscriptionInfo> subscriberContainer;
|
||||||
private Store store;
|
private Store store;
|
||||||
private static final String TOPIC_SUB_NAME = "tsn";
|
private static final String TOPIC_SUB_NAME = "tsn";
|
||||||
|
|
||||||
|
@ -58,6 +58,11 @@ public class KahaTopicReferenceStore extends KahaReferenceStore implements Topic
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void dispose(ConnectionContext context) {
|
||||||
|
super.dispose(context);
|
||||||
|
subscriberContainer.delete();
|
||||||
|
}
|
||||||
|
|
||||||
protected MessageId getMessageId(Object object) {
|
protected MessageId getMessageId(Object object) {
|
||||||
return new MessageId(((ReferenceRecord)object).getMessageId());
|
return new MessageId(((ReferenceRecord)object).getMessageId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.activemq.command.MessageAck;
|
||||||
import org.apache.activemq.command.MessageId;
|
import org.apache.activemq.command.MessageId;
|
||||||
import org.apache.activemq.store.MessageRecoveryListener;
|
import org.apache.activemq.store.MessageRecoveryListener;
|
||||||
import org.apache.activemq.store.MessageStore;
|
import org.apache.activemq.store.MessageStore;
|
||||||
|
import org.apache.activemq.store.AbstractMessageStore;
|
||||||
import org.apache.activemq.usage.MemoryUsage;
|
import org.apache.activemq.usage.MemoryUsage;
|
||||||
import org.apache.activemq.usage.SystemUsage;
|
import org.apache.activemq.usage.SystemUsage;
|
||||||
|
|
||||||
|
@ -39,9 +40,8 @@ import org.apache.activemq.usage.SystemUsage;
|
||||||
*
|
*
|
||||||
* @version $Revision: 1.7 $
|
* @version $Revision: 1.7 $
|
||||||
*/
|
*/
|
||||||
public class MemoryMessageStore implements MessageStore {
|
public class MemoryMessageStore extends AbstractMessageStore {
|
||||||
|
|
||||||
protected final ActiveMQDestination destination;
|
|
||||||
protected final Map<MessageId, Message> messageTable;
|
protected final Map<MessageId, Message> messageTable;
|
||||||
protected MessageId lastBatchId;
|
protected MessageId lastBatchId;
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ public class MemoryMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryMessageStore(ActiveMQDestination destination, Map<MessageId, Message> messageTable) {
|
public MemoryMessageStore(ActiveMQDestination destination, Map<MessageId, Message> messageTable) {
|
||||||
this.destination = destination;
|
super(destination);
|
||||||
this.messageTable = Collections.synchronizedMap(messageTable);
|
this.messageTable = Collections.synchronizedMap(messageTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,22 +108,12 @@ public class MemoryMessageStore implements MessageStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAllMessages(ConnectionContext context) throws IOException {
|
public void removeAllMessages(ConnectionContext context) throws IOException {
|
||||||
synchronized (messageTable) {
|
synchronized (messageTable) {
|
||||||
messageTable.clear();
|
messageTable.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActiveMQDestination getDestination() {
|
|
||||||
return destination;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
public void delete() {
|
||||||
synchronized (messageTable) {
|
synchronized (messageTable) {
|
||||||
messageTable.clear();
|
messageTable.clear();
|
||||||
|
@ -160,13 +150,4 @@ public class MemoryMessageStore implements MessageStore {
|
||||||
public void resetBatching() {
|
public void resetBatching() {
|
||||||
lastBatchId = null;
|
lastBatchId = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param memoeyUSage
|
|
||||||
* @see org.apache.activemq.store.MessageStore#setMemoryUsage(org.apache.activemq.usage.MemoryUsage)
|
|
||||||
*/
|
|
||||||
public void setMemoryUsage(MemoryUsage memoeyUSage){
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,9 @@ public class SimpleTopicTest extends TestCase {
|
||||||
private static final Log LOG = LogFactory.getLog(SimpleTopicTest.class);
|
private static final Log LOG = LogFactory.getLog(SimpleTopicTest.class);
|
||||||
|
|
||||||
protected BrokerService broker;
|
protected BrokerService broker;
|
||||||
protected String clientURI="tcp://localhost:61616?wireFormat.cacheEnabled=true&wireFormat.tightEncodingEnabled=true&jms.useAsyncSend=false&wireFormat.maxInactivityDuration=50000";
|
protected String clientURI="tcp://localhost:61616?wireFormat.cacheEnabled=true&wireFormat.tightEncodingEnabled=true&jms.useAsyncSend=false&wireFormat.maxInactivityDuration=0";
|
||||||
//protected String clientURI="tcp://localhost:61616";
|
//protected String clientURI="tcp://localhost:61616";
|
||||||
protected String bindAddress="tcp://localhost:61616";
|
protected String bindAddress="tcp://localhost:61616?wireFormat.maxInactivityDuration=0";
|
||||||
//protected String bindAddress = "tcp://localhost:61616";
|
//protected String bindAddress = "tcp://localhost:61616";
|
||||||
//protected String bindAddress="vm://localhost?marshal=true";
|
//protected String bindAddress="vm://localhost?marshal=true";
|
||||||
//protected String bindAddress="vm://localhost";
|
//protected String bindAddress="vm://localhost";
|
||||||
|
@ -51,7 +51,7 @@ public class SimpleTopicTest extends TestCase {
|
||||||
protected int numberofProducers = 1;
|
protected int numberofProducers = 1;
|
||||||
protected int totalNumberOfProducers;
|
protected int totalNumberOfProducers;
|
||||||
protected int totalNumberOfConsumers;
|
protected int totalNumberOfConsumers;
|
||||||
protected int playloadSize = 1024;
|
protected int playloadSize = 12;
|
||||||
protected byte[] array;
|
protected byte[] array;
|
||||||
protected ConnectionFactory factory;
|
protected ConnectionFactory factory;
|
||||||
|
|
||||||
|
|
|
@ -42,28 +42,32 @@ public class SlowConsumerTopicTest extends SimpleTopicTest {
|
||||||
|
|
||||||
|
|
||||||
protected PerfConsumer createConsumer(ConnectionFactory fac, Destination dest, int number) throws JMSException {
|
protected PerfConsumer createConsumer(ConnectionFactory fac, Destination dest, int number) throws JMSException {
|
||||||
return new SlowConsumer(fac, dest);
|
PerfConsumer result = new SlowConsumer(fac, dest);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PerfProducer createProducer(ConnectionFactory fac, Destination dest, int number, byte[] payload) throws JMSException {
|
protected PerfProducer createProducer(ConnectionFactory fac, Destination dest, int number, byte[] payload) throws JMSException {
|
||||||
PerfProducer result = super.createProducer(fac, dest, number, payload);
|
PerfProducer result = super.createProducer(fac, dest, number, payload);
|
||||||
result.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
|
result.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
|
||||||
|
result.setSleep(10);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BrokerService createBroker() throws Exception {
|
protected BrokerService createBroker(String url) throws Exception {
|
||||||
Resource resource = new ClassPathResource("org/apache/activemq/perf/slowConsumerBroker.xml");
|
Resource resource = new ClassPathResource("org/apache/activemq/perf/slowConsumerBroker.xml");
|
||||||
|
System.err.println("CREATE BROKER FROM " + resource);
|
||||||
BrokerFactoryBean factory = new BrokerFactoryBean(resource);
|
BrokerFactoryBean factory = new BrokerFactoryBean(resource);
|
||||||
factory.afterPropertiesSet();
|
factory.afterPropertiesSet();
|
||||||
BrokerService broker = factory.getBroker();
|
BrokerService broker = factory.getBroker();
|
||||||
|
|
||||||
broker.start();
|
broker.start();
|
||||||
return broker;
|
return broker;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ActiveMQConnectionFactory createConnectionFactory() throws Exception {
|
protected ActiveMQConnectionFactory createConnectionFactory(String uri) throws Exception {
|
||||||
ActiveMQConnectionFactory result = super.createConnectionFactory(bindAddress);
|
ActiveMQConnectionFactory result = super.createConnectionFactory(uri);
|
||||||
ActiveMQPrefetchPolicy policy = new ActiveMQPrefetchPolicy();
|
ActiveMQPrefetchPolicy policy = new ActiveMQPrefetchPolicy();
|
||||||
policy.setTopicPrefetch(1000);
|
policy.setTopicPrefetch(10);
|
||||||
result.setPrefetchPolicy(policy);
|
result.setPrefetchPolicy(policy);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.activemq.usecases;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import javax.jms.Connection;
|
||||||
|
import javax.jms.Destination;
|
||||||
|
import javax.jms.JMSException;
|
||||||
|
import javax.jms.Message;
|
||||||
|
import javax.jms.MessageConsumer;
|
||||||
|
import javax.jms.MessageProducer;
|
||||||
|
import javax.jms.Session;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.apache.activemq.ActiveMQConnectionFactory;
|
||||||
|
import org.apache.activemq.broker.BrokerService;
|
||||||
|
import org.apache.activemq.command.ActiveMQQueue;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Rajani Chennamaneni
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DispatchMultipleConsumersTest extends TestCase {
|
||||||
|
private final static Log logger = LogFactory.getLog(DispatchMultipleConsumersTest.class);
|
||||||
|
BrokerService broker;
|
||||||
|
Destination dest;
|
||||||
|
String destinationName = "TEST.Q";
|
||||||
|
String msgStr = "Test text message";
|
||||||
|
int messagesPerThread = 20;
|
||||||
|
int producerThreads = 50;
|
||||||
|
int consumerCount = 2;
|
||||||
|
AtomicInteger sentCount;
|
||||||
|
AtomicInteger consumedCount;
|
||||||
|
CountDownLatch producerLatch;
|
||||||
|
CountDownLatch consumerLatch;
|
||||||
|
String brokerURL = "tcp://localhost:61616";
|
||||||
|
String userName = "";
|
||||||
|
String password = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
broker = new BrokerService();
|
||||||
|
broker.setPersistent(true);
|
||||||
|
broker.setUseJmx(true);
|
||||||
|
broker.deleteAllMessages();
|
||||||
|
broker.addConnector("tcp://localhost:61616");
|
||||||
|
broker.start();
|
||||||
|
dest = new ActiveMQQueue(destinationName);
|
||||||
|
resetCounters();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
// broker.stop();
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetCounters() {
|
||||||
|
sentCount = new AtomicInteger(0);
|
||||||
|
consumedCount = new AtomicInteger(0);
|
||||||
|
producerLatch = new CountDownLatch(producerThreads);
|
||||||
|
consumerLatch = new CountDownLatch(consumerCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDispatch1() {
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
resetCounters();
|
||||||
|
dispatch();
|
||||||
|
/*try {
|
||||||
|
System.out.print("Press Enter to continue/finish:");
|
||||||
|
//pause to check the counts on JConsole
|
||||||
|
System.in.read();
|
||||||
|
System.in.read();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}*/
|
||||||
|
//check for consumed messages count
|
||||||
|
assertEquals("Incorrect messages in Iteration " + i, sentCount.get(), consumedCount.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dispatch() {
|
||||||
|
startConsumers();
|
||||||
|
startProducers();
|
||||||
|
try {
|
||||||
|
producerLatch.await();
|
||||||
|
consumerLatch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("test interrupted!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startConsumers() {
|
||||||
|
ActiveMQConnectionFactory connFactory = new ActiveMQConnectionFactory(userName, password, brokerURL);
|
||||||
|
Connection conn;
|
||||||
|
try {
|
||||||
|
conn = connFactory.createConnection();
|
||||||
|
conn.start();
|
||||||
|
for (int i = 0; i < consumerCount; i++) {
|
||||||
|
new ConsumerThread(conn, "ConsumerThread"+i);
|
||||||
|
}
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error("Failed to start consumers", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startProducers() {
|
||||||
|
ActiveMQConnectionFactory connFactory = new ActiveMQConnectionFactory(userName, password, brokerURL);
|
||||||
|
for (int i = 0; i < producerThreads; i++) {
|
||||||
|
new ProducerThread(connFactory, messagesPerThread, "ProducerThread"+i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConsumerThread extends Thread {
|
||||||
|
Connection conn;
|
||||||
|
Session session;
|
||||||
|
MessageConsumer consumer;
|
||||||
|
|
||||||
|
public ConsumerThread(Connection conn, String name) {
|
||||||
|
super();
|
||||||
|
this.conn = conn;
|
||||||
|
this.setName(name);
|
||||||
|
logger.info("Created new consumer thread:" + name);
|
||||||
|
try {
|
||||||
|
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
consumer = session.createConsumer(dest);
|
||||||
|
start();
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error("Failed to start consumer thread:" + name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int msgCount = 0;
|
||||||
|
int nullCount = 0;
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Message msg = consumer.receive(1000);
|
||||||
|
if (msg == null) {
|
||||||
|
if (producerLatch.getCount() > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nullCount++;
|
||||||
|
if (nullCount > 10) {
|
||||||
|
//assume that we are not getting any more messages
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nullCount = 0;
|
||||||
|
}
|
||||||
|
Thread.sleep(100);
|
||||||
|
logger.info("Message received:" + msg.getJMSMessageID());
|
||||||
|
msgCount++;
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error("Failed to consume:", e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Interrupted!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
consumer.close();
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error("Failed to close consumer " + getName(), e);
|
||||||
|
}
|
||||||
|
consumedCount.addAndGet(msgCount);
|
||||||
|
consumerLatch.countDown();
|
||||||
|
logger.info("Consumed " + msgCount + " messages using thread " + getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ProducerThread extends Thread {
|
||||||
|
int count;
|
||||||
|
Connection conn;
|
||||||
|
Session session;
|
||||||
|
MessageProducer producer;
|
||||||
|
|
||||||
|
public ProducerThread(ActiveMQConnectionFactory connFactory, int count, String name) {
|
||||||
|
super();
|
||||||
|
this.count = count;
|
||||||
|
this.setName(name);
|
||||||
|
logger.info("Created new producer thread:" + name);
|
||||||
|
try {
|
||||||
|
conn = connFactory.createConnection();
|
||||||
|
conn.start();
|
||||||
|
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
|
||||||
|
producer = session.createProducer(dest);
|
||||||
|
start();
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error("Failed to start producer thread:" + name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
int i = 0;
|
||||||
|
try {
|
||||||
|
for (; i < count; i++) {
|
||||||
|
producer.send(session.createTextMessage(msgStr));
|
||||||
|
Thread.sleep(500);
|
||||||
|
}
|
||||||
|
conn.close();
|
||||||
|
} catch (JMSException e) {
|
||||||
|
logger.error(e.getMessage(), e);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
logger.error("Interrupted!", e);
|
||||||
|
}
|
||||||
|
sentCount.addAndGet(i);
|
||||||
|
producerLatch.countDown();
|
||||||
|
logger.info("Sent " + i + " messages from thread " + getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,10 +25,10 @@
|
||||||
<destinationPolicy>
|
<destinationPolicy>
|
||||||
<policyMap>
|
<policyMap>
|
||||||
<policyEntries>
|
<policyEntries>
|
||||||
<policyEntry topic="blob">
|
<policyEntry topic=">" producerFlowControl="false">
|
||||||
<!-- lets force old messages to be discarded for slow consumers -->
|
<!-- lets force old messages to be discarded for slow consumers -->
|
||||||
<pendingMessageLimitStrategy>
|
<pendingMessageLimitStrategy>
|
||||||
<constantPendingMessageLimitStrategy limit="10"/>
|
<constantPendingMessageLimitStrategy limit="0"/>
|
||||||
</pendingMessageLimitStrategy>
|
</pendingMessageLimitStrategy>
|
||||||
</policyEntry>
|
</policyEntry>
|
||||||
</policyEntries>
|
</policyEntries>
|
||||||
|
|
Loading…
Reference in New Issue