Search in sources :

Example 1 with TransactionBroker

use of com.sun.messaging.jmq.jmsserver.data.TransactionBroker in project openmq by eclipse-ee4j.

the class TransactionHandler method retrieveConsumedRemoteMessages.

private HashMap[] retrieveConsumedRemoteMessages(TransactionList translist, TransactionUID id, boolean checkOnly) throws BrokerException {
    HashMap mcmap = translist.retrieveConsumedMessages(id);
    HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
    if (DEBUG_CLUSTER_TXN) {
        logger.log(logger.INFO, "retrieveConsumedRemoteMessages(" + translist + ",TID=" + id + ") retrieveConsumedMessages: " + mcmap);
    }
    if (mcmap == null || mcmap.size() == 0) {
        return null;
    }
    HashMap[] rets = new HashMap[2];
    HashMap<BrokerAddress, ArrayList[]> bmmap = new HashMap<>();
    HashMap<TransactionBroker, ArrayList<TransactionAcknowledgement>> tbmmap = new HashMap<>();
    ArrayList[] bmcll = null;
    ArrayList<TransactionAcknowledgement> tbmcl = null;
    boolean hasRemote = false;
    BrokerAddress myba = Globals.getMyAddress();
    UID tranpid = translist.getPartitionedStore().getPartitionID();
    UID refpid = null;
    ConsumerUID cuid = null, scuid = null;
    TransactionAcknowledgement ta = null;
    Iterator<Map.Entry> itr = mcmap.entrySet().iterator();
    Map.Entry pair = null;
    while (itr.hasNext()) {
        pair = itr.next();
        SysMessageID sysid = (SysMessageID) pair.getKey();
        if (sysid == null) {
            continue;
        }
        PacketReference ref = DL.get(null, sysid, false);
        if (checkRefRequeued(translist, id, ref, sysid)) {
            BrokerException bex = new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_MAYBE_REROUTED, sysid) + ", TUID=" + id, Status.GONE);
            bex.setRemote(true);
            StringBuilder buf = new StringBuilder();
            List interests = (List) pair.getValue();
            for (int i = 0; i < interests.size(); i++) {
                buf.append(String.valueOf(((ConsumerUID) interests.get(i)).longValue()));
                buf.append(' ');
            }
            bex.setRemoteConsumerUIDs(buf.toString());
            throw bex;
        }
        if (ref == null) {
            throw new BrokerException(Globals.getBrokerResources().getKString(BrokerResources.X_MESSAGE_REF_GONE, sysid) + ", TUID=" + id, Status.CONFLICT);
        }
        BrokerAddress ba = ref.getBrokerAddress();
        if (ba == null) {
            if (!DL.isPartitionMode()) {
                ba = myba;
            } else {
                refpid = ref.getPartitionedStore().getPartitionID();
                ba = (BrokerAddress) myba.clone();
                ba.setStoreSessionUID(refpid);
                if (!refpid.equals(tranpid)) {
                    hasRemote = true;
                }
            }
        } else if (!hasRemote) {
            hasRemote = true;
        }
        if (hasRemote && checkOnly) {
            return rets;
        }
        TransactionBroker tba = new TransactionBroker(ba);
        bmcll = bmmap.get(tba.getBrokerAddress());
        tbmcl = tbmmap.get(tba);
        if (bmcll == null) {
            bmcll = new ArrayList[2];
            bmcll[0] = new ArrayList();
            bmcll[1] = new ArrayList();
            bmmap.put(tba.getBrokerAddress(), bmcll);
        }
        if (tbmcl == null) {
            tbmcl = new ArrayList<>();
            tbmmap.put(tba, tbmcl);
        }
        List interests = (List) mcmap.get(sysid);
        for (int i = 0; i < interests.size(); i++) {
            cuid = (ConsumerUID) interests.get(i);
            bmcll[0].add(sysid);
            bmcll[1].add(cuid);
            scuid = (ConsumerUID) sToCmap.get(cuid);
            ta = new TransactionAcknowledgement(sysid, cuid, scuid);
            if (!scuid.shouldStore() || !ref.isPersistent()) {
                ta.setShouldStore(false);
            }
            tbmcl.add(ta);
        }
        if (DEBUG_CLUSTER_TXN) {
            logger.log(logger.INFO, "retrieveConsumedRemoteMessages() for broker " + tba + ": " + Arrays.toString(bmcll) + ", " + tbmcl);
        }
    }
    if (!hasRemote) {
        return null;
    }
    rets[0] = bmmap;
    rets[1] = tbmmap;
    return rets;
}
Also used : TransactionAcknowledgement(com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) ArrayList(java.util.ArrayList) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) PacketReference(com.sun.messaging.jmq.jmsserver.core.PacketReference) SysMessageID(com.sun.messaging.jmq.io.SysMessageID) DestinationList(com.sun.messaging.jmq.jmsserver.core.DestinationList) List(java.util.List) ArrayList(java.util.ArrayList) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) Map(java.util.Map) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap)

Example 2 with TransactionBroker

use of com.sun.messaging.jmq.jmsserver.data.TransactionBroker in project openmq by eclipse-ee4j.

the class TransactionHandler method doRemotePrepare.

private ClusterTransaction doRemotePrepare(TransactionList translist, TransactionUID id, TransactionState nextState, TransactionWork txnWork) throws BrokerException {
    if (nextState.getState() != TransactionState.PREPARED) {
        throw new BrokerException("Unexpected state " + nextState + " for transactionID:" + id);
    }
    HashMap[] rets = retrieveConsumedRemoteMessages(translist, id, false);
    if (DEBUG_CLUSTER_TXN) {
        logger.log(logger.INFO, "doRemotePrepare(" + translist + ", " + id + "): retrievedConsumedRemoteMsgs:" + (rets == null ? "null" : rets[0] + ", " + rets[1]));
    }
    if (fi.FAULT_INJECTION) {
        if (fi.checkFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5, null)) {
            fi.unsetFault(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
            throw new BrokerException(fi.FAULT_MSG_REMOTE_ACK_C_TXNPREPARE_0_5);
        }
    }
    if (rets == null) {
        return null;
    }
    if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
        return null;
    }
    HashMap<BrokerAddress, ArrayList[]> bmmap = rets[0];
    TransactionBroker[] tranbas = (TransactionBroker[]) rets[1].keySet().toArray(new TransactionBroker[rets[1].size()]);
    BrokerAddress[] bas = bmmap.keySet().toArray(new BrokerAddress[bmmap.size()]);
    boolean persist = true;
    ClusterTransaction clusterTransaction = null;
    if (Globals.isNewTxnLogEnabled()) {
        // create a cluster transaction which will be logged
        clusterTransaction = new ClusterTransaction(id, nextState, txnWork, tranbas);
        translist.logClusterTransaction(id, nextState, tranbas, true, persist, clusterTransaction);
    } else {
        translist.logClusterTransaction(id, nextState, tranbas, true, persist);
    }
    if (DEBUG_CLUSTER_TXN) {
        StringBuilder buf = new StringBuilder();
        buf.append("Preparing transaction ").append(id).append(", brokers");
        for (TransactionBroker tranba : tranbas) {
            buf.append("\n\t").append(tranba);
        }
        logger.log(logger.INFO, buf.toString());
    }
    UID tranpid = null;
    if (Globals.getDestinationList().isPartitionMode()) {
        tranpid = translist.getPartitionedStore().getPartitionID();
        ArrayList<TransactionAcknowledgement> mcl = null;
        TransactionBroker tba = null;
        UID tbapid = null;
        TransactionAcknowledgement[] tas = null;
        TransactionList tl = null;
        for (int i = 0; i < tranbas.length; i++) {
            tba = tranbas[i];
            if (!tba.getBrokerAddress().equals(Globals.getMyAddress())) {
                continue;
            }
            tbapid = tba.getBrokerAddress().getStoreSessionUID();
            if (tbapid.equals(tranpid)) {
                continue;
            }
            mcl = (ArrayList<TransactionAcknowledgement>) rets[1].get(tba);
            tas = mcl.toArray(new TransactionAcknowledgement[mcl.size()]);
            tl = TransactionList.getTransListByPartitionID(tbapid);
            if (tl == null) {
                throw new BrokerException("Can't prepare transaction " + id + " because " + "transaction list for partition " + tbapid + " not found");
            }
            BrokerAddress home = (BrokerAddress) Globals.getMyAddress().clone();
            home.setStoreSessionUID(tranpid);
            tl.logLocalRemoteTransaction(id, nextState, tas, home, false, true, persist);
        }
    }
    // handle remote brokers
    ArrayList[] mcll = null;
    BrokerAddress ba = null;
    for (int i = 0; i < bas.length; i++) {
        ba = bas[i];
        if (ba == Globals.getMyAddress() || ba.equals(Globals.getMyAddress())) {
            continue;
        }
        mcll = bmmap.get(ba);
        try {
            Globals.getClusterBroadcast().acknowledgeMessage2P(ba, (SysMessageID[]) mcll[0].toArray(new SysMessageID[mcll[0].size()]), (ConsumerUID[]) mcll[1].toArray(new ConsumerUID[mcll[1].size()]), ClusterBroadcast.MSG_PREPARE, null, Long.valueOf(id.longValue()), tranpid, true, false);
        } catch (BrokerException e) {
            if (!(e instanceof BrokerDownException) && !(e instanceof AckEntryNotFoundException)) {
                throw e;
            }
            HashMap sToCmap = translist.retrieveStoredConsumerUIDs(id);
            ArrayList remoteConsumerUIDa = new ArrayList();
            StringBuilder remoteConsumerUIDs = new StringBuilder();
            String uidstr = null;
            StringBuilder debugbuf = new StringBuilder();
            for (int j = 0; j < mcll[0].size(); j++) {
                SysMessageID sysid = (SysMessageID) mcll[0].get(j);
                ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
                ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
                if (suid == null || suid.equals(uid)) {
                    continue;
                }
                if (e.isRemote()) {
                    uidstr = String.valueOf(uid.longValue());
                    if (!remoteConsumerUIDa.contains(uidstr)) {
                        remoteConsumerUIDa.add(uidstr);
                        remoteConsumerUIDs.append(uidstr);
                        remoteConsumerUIDs.append(' ');
                        Consumer c = Consumer.getConsumer(uid);
                        if (c != null) {
                            c.recreationRequested();
                        } else {
                            logger.log(logger.WARNING, "Consumer " + uid + " not found in processing remote exception on preparing transaction " + id);
                        }
                    }
                }
                debugbuf.append("\n\t[").append(sysid).append(':').append(uid).append(']');
            }
            if (e.isRemote()) {
                e.setRemoteConsumerUIDs(remoteConsumerUIDs.toString());
                if (DEBUG_CLUSTER_TXN) {
                    logger.log(logger.INFO, "doRemotePrepare: JMQRemote Exception:remoteConsumerUIDs=" + remoteConsumerUIDs + ", remote broker " + ba);
                }
            }
            try {
                translist.updateState(id, TransactionState.FAILED, false, TransactionState.PREPARED, true);
            } catch (Exception ex) {
                logger.logStack(logger.WARNING, "Unable to update transaction " + id + " state to FAILED on PREPARE failure from " + ba + ": " + ex.getMessage() + debugbuf.toString(), ex);
                throw e;
            }
            if (e instanceof AckEntryNotFoundException) {
                mcll = ((AckEntryNotFoundException) e).getAckEntries();
            }
            for (int j = 0; j < mcll[0].size(); j++) {
                SysMessageID sysid = (SysMessageID) mcll[0].get(j);
                ConsumerUID uid = (ConsumerUID) mcll[1].get(j);
                boolean remove = true;
                if (e instanceof BrokerDownException) {
                    ConsumerUID suid = (ConsumerUID) sToCmap.get(uid);
                    if (suid == null || suid.equals(uid)) {
                        if (DEBUG_CLUSTER_TXN) {
                            logger.log(logger.INFO, "doRemotePrepare: no remove txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
                        }
                        remove = false;
                    }
                }
                if (remove) {
                    try {
                        translist.removeAcknowledgement(id, sysid, uid, (e instanceof AckEntryNotFoundException));
                        if (DEBUG_CLUSTER_TXN) {
                            logger.log(logger.INFO, "doRemotePrepare: removed txnack " + sysid + ", " + uid + " for BrokerDownException from " + ba);
                        }
                    } catch (Exception ex) {
                        logger.logStack(logger.WARNING, "Unable to remove transaction " + id + " ack [" + sysid + ":" + uid + "] on PREPARE failure from " + ba + ": " + ex.getMessage(), ex);
                    }
                }
            }
            logger.log(logger.WARNING, "Preparing transaction " + id + " failed from " + ba + ": " + e.getMessage() + debugbuf.toString());
            throw e;
        }
    }
    return clusterTransaction;
}
Also used : BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) HashMap(java.util.HashMap) CacheHashMap(com.sun.messaging.jmq.util.CacheHashMap) ArrayList(java.util.ArrayList) ClusterTransaction(com.sun.messaging.jmq.jmsserver.data.ClusterTransaction) Consumer(com.sun.messaging.jmq.jmsserver.core.Consumer) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) TransactionAcknowledgement(com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) BrokerAddress(com.sun.messaging.jmq.jmsserver.core.BrokerAddress) BrokerDownException(com.sun.messaging.jmq.jmsserver.util.BrokerDownException) SelectorFormatException(com.sun.messaging.jmq.util.selector.SelectorFormatException) IOException(java.io.IOException) AckEntryNotFoundException(com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException) MaxConsecutiveRollbackException(com.sun.messaging.jmq.jmsserver.util.MaxConsecutiveRollbackException) BrokerException(com.sun.messaging.jmq.jmsserver.util.BrokerException) ConsumerUID(com.sun.messaging.jmq.jmsserver.core.ConsumerUID) DestinationUID(com.sun.messaging.jmq.jmsserver.core.DestinationUID) UID(com.sun.messaging.jmq.util.UID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) SysMessageID(com.sun.messaging.jmq.io.SysMessageID)

Example 3 with TransactionBroker

use of com.sun.messaging.jmq.jmsserver.data.TransactionBroker in project openmq by eclipse-ee4j.

the class RaptorProtocol method sendRemoteTransactionInfo.

private void sendRemoteTransactionInfo(TransactionUID tid, BrokerAddress to, Long xid, boolean ownerWaitingFor) {
    List<Object[]> list = TransactionList.getTransListsAndRemoteTranStates(tid);
    TransactionList tl = null;
    TransactionState ts = null;
    Object[] oo = null;
    if (list != null) {
        oo = list.get(0);
        tl = (TransactionList) oo[0];
        ts = (TransactionState) oo[1];
    }
    if (ts == null && !ownerWaitingFor) {
        if (DEBUG_CLUSTER_TXN) {
            logger.log(logger.INFO, "Remote transaction " + tid + " not found");
        }
        return;
    }
    UID tlss = null;
    boolean partitionmode = Globals.getDestinationList().isPartitionMode();
    int loop = (list == null ? 1 : list.size());
    for (int i = 0; i < loop; i++) {
        if (list != null) {
            oo = list.get(i);
            tl = (TransactionList) oo[0];
            ts = (TransactionState) oo[1];
        }
        if (ts != null && ts.getState() != TransactionState.ROLLEDBACK && ts.getState() != TransactionState.COMMITTED) {
            continue;
        }
        tlss = null;
        if (tl != null && partitionmode) {
            tlss = tl.getPartitionedStore().getPartitionID();
        }
        int s = (ts == null ? TransactionState.NULL : ts.getState());
        TransactionBroker txnhome = null;
        if (s == TransactionState.ROLLEDBACK || s == TransactionState.COMMITTED) {
            if (tl != null) {
                txnhome = tl.getRemoteTransactionHomeBroker(tid);
            }
        }
        ClusterTxnInfoInfo ii = ClusterTxnInfoInfo.newInstance(Long.valueOf(tid.longValue()), s, null, null, (txnhome == null ? null : txnhome.getBrokerAddress()), false, tlss, c, xid);
        if (DEBUG_CLUSTER_TXN) {
            logger.log(logger.INFO, Globals.getBrokerResources().getKString(BrokerResources.I_SEND_REMOTE_TXN_INFO, to, ii.toString()));
        }
        try {
            c.unicast(to, ii.getGPacket());
        } catch (Exception e) {
            String[] args = { ii.toString(), to.toString(), e.getMessage() };
            logger.log(Logger.WARNING, Globals.getBrokerResources().getString(BrokerResources.W_SEND_REMOTE_TXN_INFO_FAIL, args));
        }
    }
// for
}
Also used : TransactionState(com.sun.messaging.jmq.jmsserver.data.TransactionState) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) HandshakeInProgressException(com.sun.messaging.jmq.jmsserver.multibroker.HandshakeInProgressException)

Example 4 with TransactionBroker

use of com.sun.messaging.jmq.jmsserver.data.TransactionBroker in project openmq by eclipse-ee4j.

the class RaptorProtocol method sendPreparedTransactionInquiries.

private void sendPreparedTransactionInquiries(List<TransactionUID> tidsonly, BrokerAddress broker, UID partitionID) {
    TransactionList[] tls = Globals.getDestinationList().getTransactionList(null);
    TransactionList tl = null;
    ArrayList tids = null;
    TransactionUID tid = null;
    ClusterTxnInquiryInfo cii = null;
    TransactionBroker txnhome = null;
    UID txnhomess = null;
    for (int i = 0; i < tls.length; i++) {
        tl = tls[i];
        if (tl == null) {
            continue;
        }
        tids = tl.getPreparedRemoteTransactions(null);
        Iterator itr = tids.iterator();
        while (itr.hasNext()) {
            tid = (TransactionUID) itr.next();
            if (tidsonly != null && !tidsonly.contains(tid)) {
                continue;
            }
            txnhome = tl.getRemoteTransactionHomeBroker(tid);
            if (broker == null && txnhome == null) {
                continue;
            }
            txnhomess = null;
            if (txnhome != null) {
                txnhomess = txnhome.getBrokerAddress().getStoreSessionUID();
            }
            if (partitionID == null || txnhomess == null || txnhomess.equals(partitionID)) {
                cii = ClusterTxnInquiryInfo.newInstance(Long.valueOf(tid.longValue()), ((txnhome == null) ? null : txnhome.getCurrentBrokerAddress()), null);
                if (DEBUG_CLUSTER_TXN) {
                    logger.log(Logger.INFO, "Sending transaction inquiry: " + cii + " to " + broker);
                }
                BrokerAddress tobroker = (broker == null ? txnhome.getCurrentBrokerAddress() : broker);
                try {
                    c.unicast(tobroker, cii.getGPacket());
                } catch (Exception e) {
                    logger.log(Logger.WARNING, "Sending transaction inquiry " + cii + " to " + tobroker + " failed");
                }
            }
        }
    }
}
Also used : TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker) TransactionList(com.sun.messaging.jmq.jmsserver.data.TransactionList) HandshakeInProgressException(com.sun.messaging.jmq.jmsserver.multibroker.HandshakeInProgressException)

Example 5 with TransactionBroker

use of com.sun.messaging.jmq.jmsserver.data.TransactionBroker in project openmq by eclipse-ee4j.

the class PacketReference method acknowledged.

/**
 * If this method return true, caller is responsible to call postAcknowledgedRemoval()
 *
 * @param ackack whether client requested ackack
 *
 * If the ack is a remote non-transacted ack, waits for remote ack reply only if sync == true {@literal &&} notIgnored {@literal &&} ackack
 */
public boolean acknowledged(ConsumerUID intid, ConsumerUID storedid, boolean sync, boolean notIgnored, TransactionUID tuid, TransactionList translist, HashMap<TransactionBroker, Object> remoteNotified, boolean ackack) throws BrokerException, IOException {
    Long txn = (tuid == null ? null : Long.valueOf(tuid.longValue()));
    try {
        if (destroyed || invalid) {
            // destroyed
            return true;
        }
        removeInDelivery(storedid);
        ConsumerMessagePair cmp = getAck(storedid);
        // something went wrong, ignore
        if (cmp == null) {
            // nothing to do
            Globals.getLogger().log(Logger.ERROR, "Internal Error: Received Unknown ack " + intid + " for message " + getSysMessageID());
            Globals.getLogger().log(Logger.ERROR, "AckInfo" + ackInfo.toString());
            boolean rm = false;
            synchronized (this) {
                rm = (ackCnt + deadCnt) >= interestCnt;
            }
            if (!isLocal() && rm) {
                acquireDestroyRemoteReadLock();
                synchronized (this) {
                    rm = (ackCnt + deadCnt) >= interestCnt;
                }
                if (!rm) {
                    clearDestroyRemoteReadLock();
                }
            }
            return rm;
        }
        // acked so do nothing
        if (cmp.setState(ACKED)) {
            if (cmp.isStored()) {
                boolean acked = false;
                if (Globals.getStore().isJDBCStore()) {
                    acked = pstore.hasMessageBeenAcked(destination, msgid);
                }
                if (!acked) {
                    try {
                        // This test may fail to spot that this really is
                        // the last ack because another thread processing an
                        // ack for the same message may not have yet
                        // incremented ackCnt.
                        // However, it should not return a false positive so
                        // should be safe
                        boolean isLastAck = false;
                        synchronized (this) {
                            isLastAck = (ackCnt + 1 + deadCnt) >= interestCnt;
                        }
                        pstore.updateInterestState(destination, msgid, storedid, PartitionedStore.INTEREST_STATE_ACKNOWLEDGED, Destination.PERSIST_SYNC && sync, tuid, isLastAck);
                    } catch (Exception ex) {
                        if (ex instanceof BrokerException && ((BrokerException) ex).getStatusCode() != Status.NOT_ALLOWED && ((BrokerException) ex).getStatusCode() != Status.NOT_FOUND) {
                            Globals.getLogger().log(Logger.WARNING, "Update consumer " + storedid + " state failed for message " + msgid + ": " + ex.getMessage());
                            throw ex;
                        } else {
                            Globals.getLogger().log(Logger.DEBUGHIGH, "Update consumer " + storedid + " state failed for message " + msgid + ": " + ex.getMessage());
                        }
                    }
                }
            }
            if (!isLocal()) {
                // not local
                if (notIgnored) {
                    if (Globals.getClusterBroadcast().getClusterVersion() < ClusterBroadcast.VERSION_410) {
                        Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_ACKNOWLEDGED, null, false);
                    } else if (txn == null) {
                        Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_ACKNOWLEDGED, null, (sync && ackack));
                    } else {
                        BrokerAddress raddr = getBrokerAddress();
                        TransactionBroker traddr = new TransactionBroker(raddr);
                        if (remoteNotified.get(traddr) == null) {
                            SysMessageID[] mysysids = { this.getSysMessageID() };
                            ConsumerUID[] myintids = { intid };
                            try {
                                UID txnss = translist.getPartitionedStore().getPartitionID();
                                Globals.getClusterBroadcast().acknowledgeMessage2P(raddr, mysysids, myintids, ClusterBroadcast.MSG_ACKNOWLEDGED, null, txn, txnss, true, !commit2pwait);
                                remoteNotified.put(traddr, String.valueOf(""));
                                if (commit2pwait) {
                                    translist.completeClusterTransactionBrokerState(tuid, TransactionState.COMMITTED, raddr, true);
                                }
                            } catch (Exception e) {
                                if (e instanceof BrokerDownException) {
                                    remoteNotified.put(traddr, String.valueOf(""));
                                }
                                if (DEBUG_CLUSTER_TXN) {
                                    Globals.getLogger().logStack(Logger.WARNING, "Notify commit transaction [" + this.getSysMessageID() + ", " + intid + "]TUID=" + txn + " got response: " + e.toString(), e);
                                } else {
                                    Globals.getLogger().log(Logger.WARNING, "Notify commit transaction [" + this.getSysMessageID() + ", " + intid + "]TUID=" + txn + " got response: " + e.toString(), e);
                                }
                            }
                        // catch
                        }
                    // if
                    }
                } else {
                    try {
                        Globals.getClusterBroadcast().acknowledgeMessage(getBrokerAddress(), getSysMessageID(), intid, ClusterBroadcast.MSG_IGNORED, null, false);
                    } catch (BrokerException e) {
                        Globals.getLogger().log(Logger.DEBUG, e.getMessage());
                    }
                }
            }
        } else {
            Consumer c = Consumer.getConsumer(intid);
            if (c == null || !c.isValid() || !isLocal()) {
                // do we want to add a debug level message here
                // got it while cleaning up
                // this can only happen on topics and is a
                // non-fatal error
                // fixing the timing problem through synchronization
                // adds too much overhead <- same to !isLocal case
                boolean rm = false;
                synchronized (this) {
                    rm = ((ackCnt + deadCnt) >= interestCnt);
                }
                if (!isLocal() && rm) {
                    acquireDestroyRemoteReadLock();
                    synchronized (this) {
                        rm = ((ackCnt + deadCnt) >= interestCnt);
                    }
                    if (!rm) {
                        clearDestroyRemoteReadLock();
                    }
                }
                return rm;
            } else {
                Exception e = new Exception("double ack " + cmp);
                e.fillInStackTrace();
                Globals.getLogger().logStack(Logger.ERROR, "Received ack twice " + " on " + msgid + " for " + intid + " state is = " + cmp, e);
                boolean rm = false;
                synchronized (this) {
                    rm = ((ackCnt + deadCnt) >= interestCnt);
                }
                if (!isLocal() && rm) {
                    acquireDestroyRemoteReadLock();
                    synchronized (this) {
                        rm = ((ackCnt + deadCnt) >= interestCnt);
                    }
                    if (!rm) {
                        clearDestroyRemoteReadLock();
                    }
                }
                return rm;
            }
        }
        boolean rm = false;
        synchronized (this) {
            ackCnt++;
            rm = ((ackCnt + deadCnt) >= interestCnt);
        }
        if (!isLocal() && rm) {
            acquireDestroyRemoteReadLock();
            synchronized (this) {
                rm = ((ackCnt + deadCnt) >= interestCnt);
            }
            if (!rm) {
                clearDestroyRemoteReadLock();
            }
        }
        return rm;
    } catch (Throwable thr) {
        if (thr instanceof BrokerDownException) {
            Globals.getLogger().log(Logger.WARNING, Globals.getBrokerResources().getKString(BrokerResources.W_UNABLE_PROCESS_REMOTE_ACK_BECAUSE, "[" + msgid + "]" + intid + ":" + storedid, thr.getMessage()));
        } else {
            Globals.getLogger().logStack(Logger.ERROR, "Error in processing ack" + " on " + msgid + " for " + intid, thr);
        }
        if (thr instanceof BrokerException) {
            throw (BrokerException) thr;
        }
        throw new BrokerException("Unable to process ack", thr);
    }
}
Also used : UID(com.sun.messaging.jmq.util.UID) ConnectionUID(com.sun.messaging.jmq.jmsserver.service.ConnectionUID) TransactionUID(com.sun.messaging.jmq.jmsserver.data.TransactionUID) TransactionBroker(com.sun.messaging.jmq.jmsserver.data.TransactionBroker)

Aggregations

TransactionBroker (com.sun.messaging.jmq.jmsserver.data.TransactionBroker)26 TransactionUID (com.sun.messaging.jmq.jmsserver.data.TransactionUID)10 BrokerAddress (com.sun.messaging.jmq.jmsserver.core.BrokerAddress)9 TransactionState (com.sun.messaging.jmq.jmsserver.data.TransactionState)8 IOException (java.io.IOException)8 BrokerException (com.sun.messaging.jmq.jmsserver.util.BrokerException)7 SysMessageID (com.sun.messaging.jmq.io.SysMessageID)6 ConsumerUID (com.sun.messaging.jmq.jmsserver.core.ConsumerUID)6 TransactionList (com.sun.messaging.jmq.jmsserver.data.TransactionList)6 ConnectionUID (com.sun.messaging.jmq.jmsserver.service.ConnectionUID)5 PacketReference (com.sun.messaging.jmq.jmsserver.core.PacketReference)4 TransactionAcknowledgement (com.sun.messaging.jmq.jmsserver.data.TransactionAcknowledgement)4 HandshakeInProgressException (com.sun.messaging.jmq.jmsserver.multibroker.HandshakeInProgressException)4 TransactionInfo (com.sun.messaging.jmq.jmsserver.persist.api.TransactionInfo)4 AckEntryNotFoundException (com.sun.messaging.jmq.jmsserver.util.AckEntryNotFoundException)4 UID (com.sun.messaging.jmq.util.UID)4 SelectorFormatException (com.sun.messaging.jmq.util.selector.SelectorFormatException)4 DestinationUID (com.sun.messaging.jmq.jmsserver.core.DestinationUID)3 BrokerDownException (com.sun.messaging.jmq.jmsserver.util.BrokerDownException)3 MaxConsecutiveRollbackException (com.sun.messaging.jmq.jmsserver.util.MaxConsecutiveRollbackException)3