mirror of https://github.com/apache/activemq.git
git-svn-id: https://svn.apache.org/repos/asf/incubator/activemq/trunk@490007 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
3be0113228
commit
d8674a0fed
|
@ -18,12 +18,12 @@
|
||||||
package org.apache.activemq.broker.region;
|
package org.apache.activemq.broker.region;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
import javax.jms.InvalidSelectorException;
|
import javax.jms.InvalidSelectorException;
|
||||||
import javax.jms.JMSException;
|
import javax.jms.JMSException;
|
||||||
|
|
||||||
import org.apache.activemq.broker.Broker;
|
import org.apache.activemq.broker.Broker;
|
||||||
import org.apache.activemq.broker.ConnectionContext;
|
import org.apache.activemq.broker.ConnectionContext;
|
||||||
import org.apache.activemq.broker.region.cursors.PendingMessageCursor;
|
import org.apache.activemq.broker.region.cursors.PendingMessageCursor;
|
||||||
|
@ -56,11 +56,10 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
final protected LinkedList dispatched=new LinkedList();
|
final protected LinkedList dispatched=new LinkedList();
|
||||||
|
|
||||||
protected int prefetchExtension=0;
|
protected int prefetchExtension=0;
|
||||||
boolean dispatching=false;
|
|
||||||
|
|
||||||
long enqueueCounter;
|
protected long enqueueCounter;
|
||||||
long dispatchCounter;
|
protected long dispatchCounter;
|
||||||
long dequeueCounter;
|
protected long dequeueCounter;
|
||||||
|
|
||||||
public PrefetchSubscription(Broker broker,ConnectionContext context,ConsumerInfo info, PendingMessageCursor cursor)
|
public PrefetchSubscription(Broker broker,ConnectionContext context,ConsumerInfo info, PendingMessageCursor cursor)
|
||||||
throws InvalidSelectorException{
|
throws InvalidSelectorException{
|
||||||
|
@ -123,7 +122,6 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(MessageReference node) throws Exception{
|
public void add(MessageReference node) throws Exception{
|
||||||
try {
|
|
||||||
boolean pendingEmpty=false;
|
boolean pendingEmpty=false;
|
||||||
synchronized(pending){
|
synchronized(pending){
|
||||||
pendingEmpty=pending.isEmpty();
|
pendingEmpty=pending.isEmpty();
|
||||||
|
@ -134,17 +132,16 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
}else{
|
}else{
|
||||||
optimizePrefetch();
|
optimizePrefetch();
|
||||||
synchronized(pending){
|
synchronized(pending){
|
||||||
if(log.isDebugEnabled() && pending.isEmpty()){
|
if(pending.isEmpty()&&log.isDebugEnabled()){
|
||||||
log.debug("Prefetch limit.");
|
log.debug("Prefetch limit.");
|
||||||
}
|
}
|
||||||
pending.addMessageLast(node);
|
pending.addMessageLast(node);
|
||||||
}
|
}
|
||||||
|
//we might be able to dispatch messages (i.e. not full() anymore)
|
||||||
|
dispatchMatched();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}catch(Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void processMessageDispatchNotification(MessageDispatchNotification mdn) throws Exception{
|
public void processMessageDispatchNotification(MessageDispatchNotification mdn) throws Exception{
|
||||||
synchronized(pending){
|
synchronized(pending){
|
||||||
|
@ -169,6 +166,7 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
|
|
||||||
public void acknowledge(final ConnectionContext context,final MessageAck ack) throws Exception{
|
public void acknowledge(final ConnectionContext context,final MessageAck ack) throws Exception{
|
||||||
// Handle the standard acknowledgment case.
|
// Handle the standard acknowledgment case.
|
||||||
|
boolean callDispatchMatched=false;
|
||||||
synchronized(dispatched){
|
synchronized(dispatched){
|
||||||
if(ack.isStandardAck()){
|
if(ack.isStandardAck()){
|
||||||
// Acknowledge all dispatched messages up till the message id of the acknowledgment.
|
// Acknowledge all dispatched messages up till the message id of the acknowledgment.
|
||||||
|
@ -216,13 +214,15 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
}else{
|
}else{
|
||||||
prefetchExtension=Math.max(0,prefetchExtension-(index+1));
|
prefetchExtension=Math.max(0,prefetchExtension-(index+1));
|
||||||
}
|
}
|
||||||
dispatchMatched();
|
callDispatchMatched=true;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this only happens after a reconnect - get an ack which is not valid
|
// this only happens after a reconnect - get an ack which is not valid
|
||||||
|
if(!callDispatchMatched){
|
||||||
log.info("Could not correlate acknowledgment with dispatched message: "+ack);
|
log.info("Could not correlate acknowledgment with dispatched message: "+ack);
|
||||||
|
}
|
||||||
}else if(ack.isDeliveredAck()){
|
}else if(ack.isDeliveredAck()){
|
||||||
// Message was delivered but not acknowledged: update pre-fetch counters.
|
// Message was delivered but not acknowledged: update pre-fetch counters.
|
||||||
// Acknowledge all dispatched messages up till the message id of the acknowledgment.
|
// Acknowledge all dispatched messages up till the message id of the acknowledgment.
|
||||||
|
@ -231,11 +231,13 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
final MessageReference node=(MessageReference)iter.next();
|
final MessageReference node=(MessageReference)iter.next();
|
||||||
if(ack.getLastMessageId().equals(node.getMessageId())){
|
if(ack.getLastMessageId().equals(node.getMessageId())){
|
||||||
prefetchExtension=Math.max(prefetchExtension,index+1);
|
prefetchExtension=Math.max(prefetchExtension,index+1);
|
||||||
dispatchMatched();
|
callDispatchMatched=true;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!callDispatchMatched){
|
||||||
throw new JMSException("Could not correlate acknowledgment with dispatched message: "+ack);
|
throw new JMSException("Could not correlate acknowledgment with dispatched message: "+ack);
|
||||||
|
}
|
||||||
}else if(ack.isPoisonAck()){
|
}else if(ack.isPoisonAck()){
|
||||||
// TODO: what if the message is already in a DLQ???
|
// TODO: what if the message is already in a DLQ???
|
||||||
// Handle the poison ACK case: we need to send the message to a DLQ
|
// Handle the poison ACK case: we need to send the message to a DLQ
|
||||||
|
@ -259,14 +261,19 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
acknowledge(context,ack,node);
|
acknowledge(context,ack,node);
|
||||||
if(ack.getLastMessageId().equals(messageId)){
|
if(ack.getLastMessageId().equals(messageId)){
|
||||||
prefetchExtension=Math.max(0,prefetchExtension-(index+1));
|
prefetchExtension=Math.max(0,prefetchExtension-(index+1));
|
||||||
dispatchMatched();
|
callDispatchMatched=true;
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!callDispatchMatched){
|
||||||
throw new JMSException("Could not correlate acknowledgment with dispatched message: "+ack);
|
throw new JMSException("Could not correlate acknowledgment with dispatched message: "+ack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(callDispatchMatched){
|
||||||
|
dispatchMatched();
|
||||||
|
}else{
|
||||||
if(isSlaveBroker()){
|
if(isSlaveBroker()){
|
||||||
throw new JMSException("Slave broker out of sync with master: Acknowledgment ("+ack
|
throw new JMSException("Slave broker out of sync with master: Acknowledgment ("+ack
|
||||||
+") was not in the dispatch list: "+dispatched);
|
+") was not in the dispatch list: "+dispatched);
|
||||||
|
@ -368,39 +375,46 @@ abstract public class PrefetchSubscription extends AbstractSubscription{
|
||||||
|
|
||||||
public void add(ConnectionContext context,Destination destination) throws Exception{
|
public void add(ConnectionContext context,Destination destination) throws Exception{
|
||||||
super.add(context,destination);
|
super.add(context,destination);
|
||||||
|
synchronized(pending){
|
||||||
pending.add(context,destination);
|
pending.add(context,destination);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(ConnectionContext context,Destination destination) throws Exception{
|
public void remove(ConnectionContext context,Destination destination) throws Exception{
|
||||||
super.remove(context,destination);
|
super.remove(context,destination);
|
||||||
|
synchronized(pending){
|
||||||
pending.remove(context,destination);
|
pending.remove(context,destination);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected void dispatchMatched() throws IOException{
|
protected void dispatchMatched() throws IOException{
|
||||||
|
List toDispatch=null;
|
||||||
synchronized(pending){
|
synchronized(pending){
|
||||||
if(!dispatching){
|
|
||||||
dispatching=true;
|
|
||||||
try{
|
try{
|
||||||
pending.reset();
|
pending.reset();
|
||||||
while(pending.hasNext()&&!isFull()){
|
while(pending.hasNext()&&!isFull()){
|
||||||
MessageReference node=pending.next();
|
MessageReference node=pending.next();
|
||||||
pending.remove();
|
pending.remove();
|
||||||
|
|
||||||
// Message may have been sitting in the pending list a while
|
// Message may have been sitting in the pending list a while
|
||||||
// waiting for the consumer to ak the message.
|
// waiting for the consumer to ak the message.
|
||||||
if(node!=QueueMessageReference.NULL_MESSAGE&&node.isExpired()){
|
if(node!=QueueMessageReference.NULL_MESSAGE&&node.isExpired()){
|
||||||
continue; // just drop it.
|
continue; // just drop it.
|
||||||
}
|
}
|
||||||
|
if(toDispatch==null){
|
||||||
dispatch(node);
|
toDispatch=new ArrayList();
|
||||||
|
}
|
||||||
|
toDispatch.add(node);
|
||||||
}
|
}
|
||||||
}finally{
|
}finally{
|
||||||
pending.release();
|
pending.release();
|
||||||
dispatching=false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(toDispatch!=null){
|
||||||
|
for(int i=0;i<toDispatch.size();i++){
|
||||||
|
MessageReference node=(MessageReference)toDispatch.get(i);
|
||||||
|
dispatch(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue