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;
  }
Пример #2
0
  // 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();
    }