Globals.getHAEnabled() && haMonitor != null &&
haMonitor.checkTakingoverDestination(this));
s = new TreeSet(new RefCompare());
while (msgs.hasMoreElements()) {
Packet p = (Packet)msgs.nextElement();
PacketReference pr =PacketReference.createReference(p, uid, null);
if (takeoverMsgs != null && takeoverMsgs.contains(pr)) {
pr = null;
continue;
}
if (takingoverCheck && haMonitor.checkTakingoverMessage(p)) {
pr = null;
continue;
}
if (neverExpire)
pr.overrideExpireTime(0);
// mark already stored and make packet a SoftReference to
// prevent running out of memory if dest has lots of msgs
pr.setLoaded();
if (DEBUG) {
logger.log(Logger.INFO,"Loaded Message " + p +
" into destination " + this);
}
try {
if (!isDMQ && !addNewMessage(false, pr)) {
// expired
deadMsgs.add(pr);
}
} catch (Exception ex) {
String args[] = { pr.getSysMessageID().toString(),
pr.getDestinationUID().toString(),
ex.getMessage() };
logger.logStack(Logger.WARNING,
BrokerResources.W_CAN_NOT_LOAD_MSG,
args, ex);
continue;
}
s.add(pr);
packetlistAdd(pr.getSysMessageID(), pr.getDestinationUID());
curcnt ++;
if (curcnt > 0 && (curcnt % LOAD_COUNT == 0
|| (curcnt > LOAD_COUNT && curcnt == size))) {
String args[] = { toString(),
String.valueOf(curcnt),
String.valueOf(maxloadcnt),
String.valueOf((curcnt*100)/maxloadcnt) };
logger.log(Logger.INFO,
BrokerResources.I_LOADING_DEST_IN_PROCESS,
args);
}
}
} finally {
store.closeEnumeration(msgs);
}
// now we're sorted, process
Iterator itr = s.iterator();
while (itr.hasNext()) {
PacketReference pr = (PacketReference)itr.next();
// ok .. see if we need to remove the message
ConsumerUID[] consumers = store.
getConsumerUIDs(getDestinationUID(),
pr.getSysMessageID());
if (consumers == null) consumers = new ConsumerUID[0];
if (consumers.length == 0 &&
store.hasMessageBeenAcked(uid,pr.getSysMessageID())) {
if (DEBUG) {
logger.log(Logger.INFO,"Message " +
pr.getSysMessageID()+"["+this+"] has been acked, destory..");
}
decrementDestinationSize(pr);
removePacketList(pr.getSysMessageID(), pr.getDestinationUID());
pr.destroy();
continue;
}
if (consumers.length > 0) {
pr.setStoredWithInterest(true);
} else {
pr.setStoredWithInterest(false);
}
// first producer side transactions
boolean dontRoute = false;
if (pr.getTransactionID() != null) {
// if unrouted and not in rollback -> remove
Boolean state = (Boolean) (transactionStates == null ?
null : transactionStates.get(
pr.getTransactionID()));
// at this point, we should be down to 3 states
if (state == null ) // committed
{
if (consumers.length == 0) {
// route the message, it depends on the type of
// message
try {
consumers = routeLoadedTransactionMessage(pr);
} catch (Exception ex) {
logger.log(Logger.INFO,"Internal Error "
+ "loading/routing transacted message, "
+ "throwing out message " +
pr.getSysMessageID(), ex);
}
if (consumers.length > 0) {
int[] states = new int[consumers.length];
for (int i=0; i < states.length; i ++)
states[i] = Store.INTEREST_STATE_ROUTED;
try {
Globals.getStore().storeInterestStates(
getDestinationUID(),
pr.getSysMessageID(),
consumers, states, true, null);
pr.setStoredWithInterest(true);
} catch (Exception ex) {
// ok .. maybe weve already been routed
}
} else {
if (DEBUG) {
logger.log(Logger.INFO, "Message "+pr.getSysMessageID()+
" [TUID="+pr.getTransactionID()+", "+this+"] no interest" +", destroy...");
}
decrementDestinationSize(pr);
removePacketList(pr.getSysMessageID(), pr.getDestinationUID());
pr.destroy();
continue;
}
}
} else if (state == Boolean.TRUE) // prepared
{
if (preparedTrans == null)
preparedTrans = new LinkedHashMap();
preparedTrans.put(pr.getSysMessageID(),
pr.getTransactionID());
dontRoute = true;
} else { // rolledback
if (DEBUG) {
logger.log(Logger.INFO, "Message "+pr.getSysMessageID()+
" [TUID="+pr.getTransactionID()+", "+this+"] to be rolled back" +", destroy...");
}
decrementDestinationSize(pr);
removePacketList(pr.getSysMessageID(), pr.getDestinationUID());
pr.destroy();
continue;
}
}
// if the message has a transactionID AND there are
// no consumers, we never had time to route it
//
if (consumers.length == 0 && !dontRoute) {
logger.log(Logger.DEBUG,"Unrouted packet " + pr+", "+this);
decrementDestinationSize(pr);
removePacketList(pr.getSysMessageID(), pr.getDestinationUID());
pr.destroy();
continue;
}
int states[] = new int[consumers.length];
for (int i = 0; i < consumers.length; i ++) {
states[i] = store.getInterestState(
getDestinationUID(),
pr.getSysMessageID(), consumers[i]);
}
if (consumers.length > 0 ) {
pr.update(consumers, states);
}
try {
putMessage(pr, AddReason.LOADED);
} catch (IllegalStateException ex) {
String args[] = { pr.getSysMessageID().toString(),
pr.getDestinationUID().toString(),
ex.getMessage() };
logger.logStack(Logger.WARNING,
BrokerResources.W_CAN_NOT_LOAD_MSG,
args, ex);
continue;
} catch (OutOfLimitsException ex) {
String args[] = { pr.getSysMessageID().toString(),
pr.getDestinationUID().toString(),
ex.getMessage() };
logger.logStack(Logger.WARNING,
BrokerResources.W_CAN_NOT_LOAD_MSG,
args, ex);
continue;
}
ExpirationInfo ei = pr.getExpiration();
if (ei != null && expireReaper != null) {
expireReaper.addExpiringMessage(ei);
}
List consumerList = Arrays.asList(consumers);
// now, deal with consumer side transactions
Map transCidToState = (Map)(preparedAcks == null ? null :
preparedAcks.get(pr.getSysMessageID()));
if (transCidToState != null) {
// ok .. this isnt code focused on performance, but
// its rarely called and only once
// new a new list that allows itr.remove()
consumerList = new ArrayList(consumerList);
Iterator citr = consumerList.iterator();
while (citr.hasNext()) {
ConsumerUID cuid = (ConsumerUID)citr.next();
TransactionUID tid = (TransactionUID)
transCidToState.get(cuid);
Boolean state = (Boolean) (transactionStates == null ?
null : transactionStates.get(
tid));
// OK for committed transactions, acknowledge
if (state == null) {
// acknowledge
if (pr.acknowledged(cuid,
cuid, false, true)) {
if (committingTrans != null && committingTrans.get(tid) != null) {
unputMessage(pr, RemoveReason.ACKNOWLEDGED);
}
decrementDestinationSize(pr);
removePacketList(pr.getSysMessageID(), pr.getDestinationUID());
pr.destroy();
continue;
}
citr.remove();
continue;
} else if (state == Boolean.TRUE) {
// for prepared transactions, dont route
citr.remove();
} else if (state == Boolean.FALSE) {
// for rolled back transactions, do nothing
if (DEBUG) {
logger.log(Logger.INFO, "Redeliver message "+
pr.getSysMessageID()+" [TUID="+tid+", "+this+"]" +" to consumer "+cuid);
}
}
}
// done processing acks
}
loaded = true; // dont recurse
if (!dontRoute) {
routeLoadedMessage(pr, consumerList);
}
}
} catch (Throwable ex) {
logger.logStack(Logger.ERROR, BrokerResources.W_LOAD_DST_FAIL,
getName(), ex);
unload(true);
}
destMessages.enforceLimits(enforceLimit);
loaded = true;
// clean up dead messages
Iterator deaditr = deadMsgs.iterator();
while (deaditr.hasNext()) {
PacketReference pr = (PacketReference)deaditr.next();
try {
if (preparedTrans != null)
preparedTrans.remove(pr.getSysMessageID());
removeMessage(pr.getSysMessageID(), RemoveReason.EXPIRED);
} catch (Exception ex) {
logger.logStack(Logger.INFO,
BrokerResources.E_INTERNAL_BROKER_ERROR,
"Processing " + pr + " while loading destination " + this, ex);
}