public MessageReference removeReferenceWithID(final long id) { synchronized (scheduledReferences) { Iterator<RefScheduled> iter = scheduledReferences.iterator(); while (iter.hasNext()) { MessageReference ref = iter.next().getRef(); if (ref.getMessage().getMessageID() == id) { iter.remove(); return ref; } } } return null; }
// amq specific behavior public void amqRollback(Set<Long> acked) throws Exception { if (tx == null) { // Might be null if XA tx = newTransaction(); } RefsOperation oper = (RefsOperation) tx.getProperty(TransactionPropertyIndexes.REFS_OPERATION); if (oper != null) { List<MessageReference> ackRefs = oper.getReferencesToAcknowledge(); Map<Long, List<MessageReference>> toAcks = new HashMap<Long, List<MessageReference>>(); for (MessageReference ref : ackRefs) { Long consumerId = ref.getConsumerId(); if (this.consumers.containsKey(consumerId)) { if (acked.contains(ref.getMessage().getMessageID())) { List<MessageReference> ackList = toAcks.get(consumerId); if (ackList == null) { ackList = new ArrayList<MessageReference>(); toAcks.put(consumerId, ackList); } ackList.add(ref); } } else { // consumer must have been closed, cancel to queue ref.getQueue().cancel(tx, ref); } } // iterate consumers if (toAcks.size() > 0) { Iterator<Entry<Long, List<MessageReference>>> iter = toAcks.entrySet().iterator(); while (iter.hasNext()) { Entry<Long, List<MessageReference>> entry = iter.next(); ServerConsumer consumer = consumers.get(entry.getKey()); ((AMQServerConsumer) consumer).amqPutBackToDeliveringList(entry.getValue()); } } } tx.rollback(); if (xa) { tx = null; } else { tx = newTransaction(); } }
public List<MessageReference> cancel(final Filter filter) { List<MessageReference> refs = new ArrayList<MessageReference>(); synchronized (scheduledReferences) { Iterator<RefScheduled> iter = scheduledReferences.iterator(); while (iter.hasNext()) { MessageReference ref = iter.next().getRef(); if (filter == null || filter.match(ref.getMessage())) { iter.remove(); refs.add(ref); } } } return refs; }
public boolean checkAndSchedule(final MessageReference ref, final boolean tail) { long deliveryTime = ref.getScheduledDeliveryTime(); if (deliveryTime > 0 && scheduledExecutor != null) { if (ScheduledDeliveryHandlerImpl.trace) { ActiveMQServerLogger.LOGGER.trace( "Scheduling delivery for " + ref + " to occur at " + deliveryTime); } addInPlace(deliveryTime, ref, tail); scheduleDelivery(deliveryTime); return true; } return false; }
public void run() { HashMap<Queue, LinkedList<MessageReference>> refs = new HashMap<Queue, LinkedList<MessageReference>>(); runnables.remove(deliveryTime); final long now = System.currentTimeMillis(); if (now < deliveryTime) { // Ohhhh... blame it on the OS // on some OSes (so far Windows only) the precision of the scheduled executor could // eventually give // an executor call earlier than it was supposed... // for that reason we will schedule it again so no messages are lost! // we can't just assume deliveryTime here as we could deliver earlier than what we are // supposed to // this is basically a hack to work around an OS or JDK bug! if (trace) { ActiveMQServerLogger.LOGGER.trace( "Scheduler is working around OS imprecisions on " + "timing and re-scheduling an executor. now=" + now + " and deliveryTime=" + deliveryTime); } ScheduledDeliveryHandlerImpl.this.scheduleDelivery(deliveryTime); } if (ScheduledDeliveryHandlerImpl.trace) { ActiveMQServerLogger.LOGGER.trace( "Is it " + System.currentTimeMillis() + " now and we are running deliveryTime = " + deliveryTime); } synchronized (scheduledReferences) { Iterator<RefScheduled> iter = scheduledReferences.iterator(); while (iter.hasNext()) { MessageReference reference = iter.next().getRef(); if (reference.getScheduledDeliveryTime() > now) { // We will delivery as long as there are messages to be delivered break; } iter.remove(); reference.setScheduledDeliveryTime(0); LinkedList<MessageReference> references = refs.get(reference.getQueue()); if (references == null) { references = new LinkedList<MessageReference>(); refs.put(reference.getQueue(), references); } if (ScheduledDeliveryHandlerImpl.trace) { ActiveMQServerLogger.LOGGER.trace( "sending message " + reference + " to delivery, deliveryTime = " + deliveryTime); } references.addFirst(reference); } if (ScheduledDeliveryHandlerImpl.trace) { ActiveMQServerLogger.LOGGER.trace("Finished loop on deliveryTime = " + deliveryTime); } } for (Map.Entry<Queue, LinkedList<MessageReference>> entry : refs.entrySet()) { Queue queue = entry.getKey(); LinkedList<MessageReference> list = entry.getValue(); if (trace) { ActiveMQServerLogger.LOGGER.trace( "Delivering " + list.size() + " elements on list to queue " + queue); } queue.addHead(list); } // Just to speed up GC refs.clear(); }