Package org.jboss.messaging.core.impl

Source Code of org.jboss.messaging.core.impl.MessagingQueue$DistributorWrapper

/*     */ package org.jboss.messaging.core.impl;
/*     */
/*     */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentHashMap;
/*     */ import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
/*     */ import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Collection;
/*     */ import java.util.Collections;
/*     */ import java.util.HashSet;
/*     */ import java.util.Iterator;
/*     */ import java.util.LinkedHashMap;
/*     */ import java.util.LinkedList;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ import org.jboss.jms.server.MessagingTimeoutFactory;
/*     */ import org.jboss.logging.Logger;
/*     */ import org.jboss.messaging.core.contract.Delivery;
/*     */ import org.jboss.messaging.core.contract.DeliveryObserver;
/*     */ import org.jboss.messaging.core.contract.Distributor;
/*     */ import org.jboss.messaging.core.contract.Filter;
/*     */ import org.jboss.messaging.core.contract.Message;
/*     */ import org.jboss.messaging.core.contract.MessageReference;
/*     */ import org.jboss.messaging.core.contract.MessageStore;
/*     */ import org.jboss.messaging.core.contract.PersistenceManager;
/*     */ import org.jboss.messaging.core.contract.PersistenceManager.InitialLoadInfo;
/*     */ import org.jboss.messaging.core.contract.Queue;
/*     */ import org.jboss.messaging.core.contract.Receiver;
/*     */ import org.jboss.messaging.core.impl.clusterconnection.MessageSucker;
/*     */ import org.jboss.messaging.core.impl.tx.Transaction;
/*     */ import org.jboss.messaging.util.prioritylinkedlist.PriorityLinkedList;
/*     */ import org.jboss.util.timeout.Timeout;
/*     */ import org.jboss.util.timeout.TimeoutFactory;
/*     */ import org.jboss.util.timeout.TimeoutTarget;
/*     */
/*     */ public class MessagingQueue extends PagingChannelSupport
/*     */   implements Queue
/*     */ {
/*  73 */   private static final Logger log = Logger.getLogger(MessagingQueue.class);
/*     */   private static final long DEFAULT_RECOVER_DELIVERIES_TIMEOUT = 3000000L;
/*     */   private int nodeID;
/*     */   protected String name;
/*     */   protected Filter filter;
/*     */   protected boolean clustered;
/*     */   protected Distributor remoteDistributor;
/*     */   protected Distributor localDistributor;
/*  91 */   private boolean trace = log.isTraceEnabled();
/*     */   private Set suckers;
/*     */   private boolean handleFlowControlForConsumers;
/*     */   private Map recoveryArea;
/*     */   private Map recoveryMap;
/*     */   private long recoverDeliveriesTimeout;
/*     */
/*     */   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm, boolean recoverable, int maxSize, Filter filter, int fullSize, int pageSize, int downCacheSize, boolean clustered, long recoverDeliveriesTimeout)
/*     */   {
/* 110 */     super(id, ms, pm, recoverable, maxSize, fullSize, pageSize, downCacheSize);
/*     */
/* 112 */     setup(nodeID, name, filter, clustered, recoverDeliveriesTimeout);
/*     */   }
/*     */
/*     */   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm, boolean recoverable, Filter filter, boolean clustered)
/*     */   {
/* 122 */     super(id, ms, pm, recoverable, -1, 100000, 2000, 2000);
/*     */
/* 124 */     setup(nodeID, name, filter, clustered, 3000000L);
/*     */   }
/*     */
/*     */   public MessagingQueue(int nodeID, String name, long id, MessageStore ms, PersistenceManager pm, boolean recoverable, int maxSize, Filter filter, boolean clustered)
/*     */   {
/* 131 */     super(id, ms, pm, recoverable, maxSize);
/*     */
/* 133 */     setup(nodeID, name, filter, clustered, 3000000L);
/*     */   }
/*     */
/*     */   public MessagingQueue(int nodeID, String name, long id, boolean recoverable, Filter filter, boolean clustered)
/*     */   {
/* 140 */     super(id, null, null, recoverable, -1);
/*     */
/* 142 */     setup(nodeID, name, filter, clustered, 3000000L);
/*     */   }
/*     */
/*     */   private void setup(int nodeID, String name, Filter filter, boolean clustered, long recoverDeliveriesTimeout)
/*     */   {
/* 147 */     this.nodeID = nodeID;
/*     */
/* 149 */     this.name = name;
/*     */
/* 151 */     this.filter = filter;
/*     */
/* 153 */     this.clustered = clustered;
/*     */
/* 155 */     this.recoverDeliveriesTimeout = recoverDeliveriesTimeout;
/*     */
/* 157 */     this.localDistributor = new DistributorWrapper(new RoundRobinDistributor());
/*     */
/* 159 */     this.remoteDistributor = new DistributorWrapper(new RoundRobinDistributor());
/*     */
/* 161 */     this.distributor = new ClusterRoundRobinDistributor(this.localDistributor, this.remoteDistributor);
/*     */
/* 163 */     this.suckers = new HashSet();
/*     */
/* 165 */     this.recoveryArea = new ConcurrentReaderHashMap();
/*     */
/* 167 */     this.recoveryMap = Collections.synchronizedMap(new LinkedHashMap());
/*     */   }
/*     */
/*     */   public int getNodeID()
/*     */   {
/* 175 */     return this.nodeID;
/*     */   }
/*     */
/*     */   public String getName()
/*     */   {
/* 180 */     return this.name;
/*     */   }
/*     */
/*     */   public Filter getFilter()
/*     */   {
/* 185 */     return this.filter;
/*     */   }
/*     */
/*     */   public boolean isClustered()
/*     */   {
/* 190 */     return this.clustered;
/*     */   }
/*     */
/*     */   public Distributor getLocalDistributor()
/*     */   {
/* 195 */     return this.localDistributor;
/*     */   }
/*     */
/*     */   public Distributor getRemoteDistributor()
/*     */   {
/* 200 */     return this.remoteDistributor;
/*     */   }
/*     */
/*     */   public void mergeIn(long theChannelID, int nodeID)
/*     */     throws Exception
/*     */   {
/* 210 */     if (this.trace) log.trace("Merging queue " + this.channelID + " node id " + nodeID + " into " + this + " initially refs:" + this.messageRefs.size());
/*     */
/* 213 */     synchronized (this.lock)
/*     */     {
/* 215 */       flushDownCache();
/*     */
/* 217 */       PersistenceManager.InitialLoadInfo ili = this.pm.mergeAndLoad(theChannelID, this.channelID, this.fullSize - this.messageRefs.size(), this.firstPagingOrder, this.nextPagingOrder);
/*     */
/* 221 */       if (this.trace) log.trace("Loaded " + ili.getRefInfos().size() + " refs");
/*     */
/* 223 */       doLoad(ili);
/*     */
/* 225 */       Map toRecover = (Map)this.recoveryArea.remove(new Integer(nodeID));
/*     */
/* 227 */       if (this.trace) log.trace("To recover is: " + toRecover);
/*     */
/* 229 */       LinkedList toTimeout = new LinkedList();
/*     */
/* 231 */       if (toRecover != null)
/*     */       {
/* 235 */         if (this.trace) log.trace("Recovery area is not empty, putting refs in recovery map");
/*     */
/* 237 */         Iterator iter = this.messageRefs.iterator();
/*     */
/* 239 */         while (iter.hasNext())
/*     */         {
/* 241 */           MessageReference ref = (MessageReference)iter.next();
/*     */
/* 243 */           Message message = ref.getMessage();
/*     */
/* 245 */           String sessionID = (String)toRecover.remove(new Long(message.getMessageID()));
/*     */
/* 247 */           if (sessionID != null)
/*     */           {
/* 249 */             if (this.trace) log.trace("Added ref " + ref + " to recovery map");
/*     */
/* 251 */             RecoveryEntry re = new RecoveryEntry();
/* 252 */             re.ref = ref;
/* 253 */             re.sessionID = sessionID;
/*     */
/* 255 */             this.recoveryMap.put(new Long(message.getMessageID()), re);
/*     */
/* 257 */             this.deliveringCount.increment();
/*     */
/* 259 */             iter.remove();
/*     */
/* 261 */             toTimeout.addLast(ref);
/*     */           }
/*     */
/*     */         }
/*     */
/* 273 */         MessagingTimeoutFactory.instance.getFactory().schedule(System.currentTimeMillis() + this.recoverDeliveriesTimeout, new ClearRecoveryMapTimeoutTarget(toTimeout));
/*     */
/* 276 */         if (this.trace) log.trace("Set timeout to fire in " + this.recoverDeliveriesTimeout);
/*     */       }
/*     */
/* 279 */       deliverInternal();
/*     */     }
/*     */   }
/*     */
/*     */   public List recoverDeliveries(List messageIds)
/*     */   {
/* 285 */     if (this.trace) log.trace("Recovering deliveries");
/*     */
/* 287 */     List refs = new ArrayList();
/*     */
/* 289 */     Iterator iter = messageIds.iterator();
/*     */
/* 291 */     while (iter.hasNext())
/*     */     {
/* 293 */       Long messageID = (Long)iter.next();
/*     */
/* 295 */       RecoveryEntry re = (RecoveryEntry)this.recoveryMap.remove(messageID);
/*     */
/* 299 */       if (re != null)
/*     */       {
/* 301 */         Delivery del = new SimpleDelivery(this, re.ref);
/*     */
/* 303 */         if (this.trace) log.trace("Recovered ref " + re.ref);
/*     */
/* 305 */         refs.add(del);
/*     */       }
/*     */     }
/*     */
/* 309 */     return refs;
/*     */   }
/*     */
/*     */   public void removeStrandedReferences(String sessionID)
/*     */   {
/* 314 */     if (this.trace) log.trace("Removing stranded references for session " + sessionID);
/*     */
/* 319 */     Iterator iter = this.recoveryMap.values().iterator();
/*     */
/* 321 */     if (this.trace) log.trace("Scanning recovery map for stray entries for session");
/*     */
/* 323 */     List toCancel = new ArrayList();
/*     */
/* 325 */     while (iter.hasNext())
/*     */     {
/* 327 */       RecoveryEntry re = (RecoveryEntry)iter.next();
/*     */
/* 329 */       if (this.trace) log.trace("Session id id " + re.sessionID);
/*     */
/* 331 */       if (re.sessionID.equals(sessionID))
/*     */       {
/* 333 */         MessageReference ref = re.ref;
/*     */
/* 335 */         iter.remove();
/*     */
/* 339 */         toCancel.add(ref);
/*     */       }
/*     */     }
/*     */
/* 343 */     for (int i = toCancel.size() - 1; i >= 0; i--)
/*     */     {
/* 345 */       MessageReference ref = (MessageReference)toCancel.get(i);
/*     */
/* 347 */       synchronized (this.lock)
/*     */       {
/* 349 */         this.messageRefs.addFirst(ref, ref.getMessage().getPriority());
/*     */
/* 352 */         this.deliveringCount.decrement();
/*     */       }
/*     */
/* 355 */       if (!this.trace) continue; log.trace("Found one, added back on queue");
/*     */     }
/*     */   }
/*     */
/*     */   public void registerSucker(MessageSucker sucker)
/*     */   {
/* 362 */     if (this.trace) log.trace(this + " Registering sucker " + sucker);
/*     */
/* 364 */     synchronized (this.lock)
/*     */     {
/* 366 */       if (!this.suckers.contains(sucker))
/*     */       {
/* 368 */         this.suckers.add(sucker);
/*     */
/* 370 */         this.handleFlowControlForConsumers = true;
/*     */
/* 372 */         if ((getReceiversReady()) && (this.localDistributor.getNumberOfReceivers() > 0))
/*     */         {
/* 374 */           if (this.trace) log.trace(this + " receivers ready so setting consumer to true");
/*     */
/* 376 */           sucker.setConsuming(true);
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   public boolean unregisterSucker(MessageSucker sucker)
/*     */   {
/* 384 */     synchronized (this.lock)
/*     */     {
/* 386 */       boolean removed = this.suckers.remove(sucker);
/*     */
/* 388 */       if ((removed) && (this.suckers.isEmpty()))
/*     */       {
/* 390 */         this.handleFlowControlForConsumers = false;
/*     */       }
/*     */
/* 393 */       return removed;
/*     */     }
/*     */   }
/*     */
/*     */   public int getFullSize()
/*     */   {
/* 399 */     return this.fullSize;
/*     */   }
/*     */
/*     */   public int getPageSize()
/*     */   {
/* 404 */     return this.pageSize;
/*     */   }
/*     */
/*     */   public int getDownCacheSize()
/*     */   {
/* 409 */     return this.downCacheSize;
/*     */   }
/*     */
/*     */   public void addToRecoveryArea(int nodeID, long messageID, String sessionID)
/*     */   {
/* 414 */     if (this.trace) log.trace("Adding message id " + messageID + " to recovery area from node " + nodeID);
/*     */
/* 420 */     Integer nid = new Integer(nodeID);
/*     */
/* 422 */     Map ids = (Map)this.recoveryArea.get(nid);
/*     */
/* 424 */     if (ids == null)
/*     */     {
/* 426 */       ids = new ConcurrentHashMap();
/*     */
/* 428 */       this.recoveryArea.put(nid, ids);
/*     */     }
/*     */
/* 431 */     ids.put(new Long(messageID), sessionID);
/*     */   }
/*     */
/*     */   public void removeFromRecoveryArea(int nodeID, long messageID)
/*     */   {
/* 436 */     if (this.trace) log.trace("Removing message id " + messageID + " to recovery area from node " + nodeID);
/*     */
/* 438 */     Integer nid = new Integer(nodeID);
/*     */
/* 440 */     Map ids = (Map)this.recoveryArea.get(nid);
/*     */
/* 446 */     if ((ids != null) && (ids.remove(new Long(messageID)) != null))
/*     */     {
/* 448 */       if (ids.isEmpty())
/*     */       {
/* 450 */         this.recoveryArea.remove(nid);
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   public void removeAllFromRecoveryArea(int nodeID)
/*     */   {
/* 457 */     if (this.trace) log.trace("Removing all from recovery area for node " + nodeID);
/*     */
/* 459 */     boolean removed = this.recoveryArea.remove(new Integer(nodeID)) != null;
/*     */
/* 461 */     if (this.trace) log.trace("Removed:" + removed);
/*     */   }
/*     */
/*     */   public void addAllToRecoveryArea(int nodeID, Map ids)
/*     */   {
/* 466 */     if (this.trace) log.trace("Adding all from recovery area for node " + nodeID + " set " + ids);
/*     */
/* 468 */     Integer nid = new Integer(nodeID);
/*     */
/* 470 */     if (!(ids instanceof ConcurrentHashMap))
/*     */     {
/* 472 */       ids = new ConcurrentHashMap(ids);
/*     */     }
/*     */
/* 475 */     if (this.trace) log.trace("Adding " + ids.size() + " ids to recovery area for node " + nodeID);
/*     */
/* 477 */     this.recoveryArea.put(nid, ids);
/*     */
/* 479 */     if (this.trace) log.trace("Added");
/*     */   }
/*     */
/*     */   public long getRecoverDeliveriesTimeout()
/*     */   {
/* 484 */     return this.recoverDeliveriesTimeout;
/*     */   }
/*     */
/*     */   public Map getRecoveryArea()
/*     */   {
/* 491 */     if (this.trace) log.trace("Getting recovery area, it is " + this.recoveryArea);
/*     */
/* 493 */     return this.recoveryArea;
/*     */   }
/*     */
/*     */   public int getRecoveryMapSize()
/*     */   {
/* 498 */     return this.recoveryMap.size();
/*     */   }
/*     */
/*     */   protected void deliverInternal()
/*     */   {
/* 505 */     super.deliverInternal();
/*     */
/* 507 */     if (this.trace) log.trace(this + " deliverInternal");
/*     */
/* 509 */     if ((this.handleFlowControlForConsumers) && (getReceiversReady()) && (this.localDistributor.getNumberOfReceivers() > 0) && (this.messageRefs.isEmpty()))
/*     */     {
/* 512 */       if (this.trace) log.trace("Informing suckers");
/*     */
/* 515 */       informSuckers(true);
/*     */     }
/*     */   }
/*     */
/*     */   protected void setReceiversReady(boolean receiversReady)
/*     */   {
/* 521 */     if (this.trace) log.trace(this + " setReceiversReady " + receiversReady);
/*     */
/* 523 */     this.receiversReady = receiversReady;
/*     */
/* 525 */     if ((this.handleFlowControlForConsumers) && (!receiversReady))
/*     */     {
/* 528 */       informSuckers(false);
/*     */     }
/*     */   }
/*     */
/*     */   public String toString()
/*     */   {
/* 536 */     return "Queue[" + System.identityHashCode(this) + "/" + this.nodeID + "/" + this.channelID + "-" + this.name + "]";
/*     */   }
/*     */
/*     */   public boolean equals(Object other)
/*     */   {
/* 541 */     if (!(other instanceof MessagingQueue))
/*     */     {
/* 543 */       return false;
/*     */     }
/*     */
/* 546 */     MessagingQueue queue = (MessagingQueue)other;
/*     */
/* 548 */     return (this.nodeID == queue.nodeID) && (this.name.equals(queue.name));
/*     */   }
/*     */
/*     */   private void informSuckers(boolean consume)
/*     */   {
/* 559 */     Iterator iter = this.suckers.iterator();
/*     */
/* 561 */     while (iter.hasNext())
/*     */     {
/* 563 */       MessageSucker sucker = (MessageSucker)iter.next();
/*     */
/* 565 */       sucker.setConsuming(consume);
/*     */     }
/*     */   }
/*     */
/*     */   private class ClearRecoveryMapTimeoutTarget
/*     */     implements TimeoutTarget
/*     */   {
/*     */     private List ids;
/*     */
/*     */     ClearRecoveryMapTimeoutTarget(List ids)
/*     */     {
/* 674 */       this.ids = ids;
/*     */     }
/*     */
/*     */     public void timedOut(Timeout timeout)
/*     */     {
/* 679 */       if (MessagingQueue.this.trace) MessagingQueue.log.trace("ClearRecoveryMap timeout fired");
/*     */
/* 681 */       Iterator iter = this.ids.iterator();
/*     */
/* 683 */       boolean added = false;
/*     */
/* 685 */       while (iter.hasNext())
/*     */       {
/* 687 */         MessageReference ref = (MessageReference)iter.next();
/*     */
/* 689 */         Object obj = MessagingQueue.this.recoveryMap.remove(new Long(ref.getMessage().getMessageID()));
/*     */
/* 691 */         if (obj != null)
/*     */         {
/* 693 */           if (MessagingQueue.this.trace) MessagingQueue.log.trace("Adding ref " + ref + " back into queue");
/*     */
/* 695 */           synchronized (MessagingQueue.this.lock)
/*     */           {
/* 697 */             MessagingQueue.this.messageRefs.addFirst(ref, ref.getMessage().getPriority());
/*     */
/* 699 */             MessagingQueue.this.deliveringCount.decrement();
/*     */           }
/*     */
/* 702 */           added = true;
/*     */         }
/*     */       }
/*     */
/* 706 */       if (added)
/*     */       {
/* 708 */         synchronized (MessagingQueue.this.lock)
/*     */         {
/* 710 */           MessagingQueue.this.deliverInternal();
/*     */         }
/*     */       }
/*     */     }
/*     */   }
/*     */
/*     */   static class RecoveryEntry
/*     */   {
/*     */     String sessionID;
/*     */     MessageReference ref;
/*     */   }
/*     */
/*     */   protected class DistributorWrapper
/*     */     implements Distributor
/*     */   {
/*     */     private Distributor distributor;
/*     */
/*     */     protected DistributorWrapper(Distributor distributor)
/*     */     {
/* 577 */       this.distributor = distributor;
/*     */     }
/*     */
/*     */     public Delivery handle(DeliveryObserver observer, MessageReference reference, Transaction tx)
/*     */     {
/* 582 */       return this.distributor.handle(observer, reference, tx);
/*     */     }
/*     */
/*     */     public boolean add(Receiver receiver)
/*     */     {
/* 587 */       if (MessagingQueue.this.trace) MessagingQueue.log.trace(this + " attempting to add receiver " + receiver);
/*     */
/* 589 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 591 */         boolean added = this.distributor.add(receiver);
/*     */
/* 593 */         if (MessagingQueue.this.trace) MessagingQueue.log.trace("receiver " + receiver + (added ? "" : " NOT") + " added");
/*     */
/* 595 */         MessagingQueue.this.setReceiversReady(true);
/*     */
/* 597 */         return added;
/*     */       }
/*     */     }
/*     */
/*     */     public void clear()
/*     */     {
/* 603 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 605 */         this.distributor.clear();
/*     */       }
/*     */     }
/*     */
/*     */     public boolean contains(Receiver receiver)
/*     */     {
/* 611 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 613 */         return this.distributor.contains(receiver);
/*     */       }
/*     */     }
/*     */
/*     */     public int getNumberOfReceivers()
/*     */     {
/* 619 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 621 */         return this.distributor.getNumberOfReceivers();
/*     */       }
/*     */     }
/*     */
/*     */     public Iterator iterator()
/*     */     {
/* 627 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 629 */         return this.distributor.iterator();
/*     */       }
/*     */     }
/*     */
/*     */     public boolean remove(Receiver receiver)
/*     */     {
/* 635 */       synchronized (MessagingQueue.this.lock)
/*     */       {
/* 637 */         boolean removed = this.distributor.remove(receiver);
/*     */
/* 639 */         if (removed)
/*     */         {
/* 641 */           if (MessagingQueue.this.localDistributor.getNumberOfReceivers() == 0)
/*     */           {
/* 644 */             MessagingQueue.this.informSuckers(false);
/*     */
/* 646 */             if (MessagingQueue.this.remoteDistributor.getNumberOfReceivers() == 0)
/*     */             {
/* 648 */               MessagingQueue.this.setReceiversReady(false);
/*     */             }
/*     */           }
/*     */         }
/*     */
/* 653 */         if (MessagingQueue.this.trace) MessagingQueue.log.trace(this + (removed ? " removed " : " did NOT remove ") + receiver);
/*     */
/* 655 */         return removed;
/*     */       }
/*     */     }
/*     */   }
/*     */ }

/* Location:           /home/mnovotny/projects/EMBEDDED_JBOSS_BETA3_COMMUNITY/embedded/output/lib/embedded-jboss/lib/jboss-embedded-all.jar
* Qualified Name:     org.jboss.messaging.core.impl.MessagingQueue
* JD-Core Version:    0.6.0
*/
TOP

Related Classes of org.jboss.messaging.core.impl.MessagingQueue$DistributorWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.