Search in sources :

Example 1 with TXLockId

use of org.apache.geode.internal.cache.locks.TXLockId in project geode by apache.

the class TXCommitMessage method memberDeparted.

public void memberDeparted(final InternalDistributedMember id, boolean crashed) {
    if (!getSender().equals(id)) {
        return;
    }
    this.dm.removeMembershipListener(this);
    ThreadGroup group = LoggingThreadGroup.createThreadGroup("TXCommitMessage Threads", logger);
    synchronized (this) {
        if (isProcessing() || this.departureNoticed) {
            if (logger.isDebugEnabled()) {
                logger.debug("Member departed: Commit data is already being processed for lockid: {}", lockId);
            }
            return;
        }
        this.departureNoticed = true;
    }
    // determine if any one of them have received a CommitProcessMessage
    if (this.farSiders != null && !this.farSiders.isEmpty()) {
        if (logger.isDebugEnabled()) {
            logger.debug("Member departed: {} sending query for CommitProcess message to other recipients.", id);
        }
        // Create a new thread, send the CommitProcessQuery, wait for a response and potentially
        // process
        Thread fellowFarSidersQuery = new Thread(group, "CommitProcessQuery Thread") {

            // Should I use a thread pool?, Darrel suggests look in DM somewhere or introduce a zero
            // sized thread pool
            @Override
            public void run() {
                final TXCommitMessage mess = TXCommitMessage.this;
                Object trackerKey = mess.getTrackerKey();
                DistributedMember member = getMemberFromTrackerKey(trackerKey);
                if (!mess.getSender().equals(member)) {
                    /*
             * Do not send a CommitProcessQueryMessage when the sender of CommitMessage is not the
             * member in the tracker key. (If this happens we are the redundant node for PR, and the
             * primary just crashed).
             */
                    txTracker.removeMessage(mess);
                    return;
                }
                CommitProcessQueryReplyProcessor replProc = new CommitProcessQueryReplyProcessor(mess.dm, mess.farSiders);
                CommitProcessQueryMessage query = new CommitProcessQueryMessage(mess.getTrackerKey(), replProc.getProcessorId());
                query.setRecipients(mess.farSiders);
                mess.dm.putOutgoing(query);
                // Wait for any one positive response or all negative responses.
                // (while() loop removed for bug 36983 - you can't loop on waitForReplies()
                TXCommitMessage.this.dm.getCancelCriterion().checkCancelInProgress(null);
                try {
                    replProc.waitForRepliesUninterruptibly();
                } catch (ReplyException e) {
                    e.handleAsUnexpected();
                }
                if (replProc.receivedACommitProcessMessage()) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Transaction associated with lockID: {} from orign {} is processing due to a received \"commit process\" message", mess.lockId, id);
                    }
                    try {
                        // Set processor to zero to avoid the ack to the now departed origin
                        mess.processorId = 0;
                        mess.basicProcess();
                    } finally {
                        txTracker.processed(mess);
                    }
                } else {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Transaction associated with lockID: {} from origin {} ignored.  No other recipients received \"commit process\" message", mess.lockId, id);
                    }
                    txTracker.removeMessage(mess);
                }
            }

            private DistributedMember getMemberFromTrackerKey(Object trackerKey) {
                if (trackerKey instanceof TXId) {
                    TXId id1 = (TXId) trackerKey;
                    return id1.getMemberId();
                } else if (trackerKey instanceof TXLockId) {
                    TXLockId id2 = (TXLockId) trackerKey;
                    return id2.getMemberId();
                }
                return null;
            }
        };
        fellowFarSidersQuery.setDaemon(true);
        fellowFarSidersQuery.start();
    } else {
        if (logger.isDebugEnabled()) {
            logger.debug("Member departed: {}. Processing commit data.", getSender());
        }
        // Optimimal case where we are the only FarSider, assume we
        // will never get the CommitProcess message, but it
        // doesn't matter since we can commit anyway.
        // Start a new thread to process the commit
        Thread originDepartedCommit = new Thread(group, "Origin Departed Commit") {

            @Override
            public void run() {
                final TXCommitMessage mess = TXCommitMessage.this;
                try {
                    // Set processor to zero to avoid the ack to the now departed origin
                    mess.processorId = 0;
                    mess.basicProcess();
                } finally {
                    txTracker.processed(mess);
                }
            }
        };
        originDepartedCommit.setDaemon(true);
        originDepartedCommit.start();
    }
}
Also used : InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) DistributedMember(org.apache.geode.distributed.DistributedMember) TXLockId(org.apache.geode.internal.cache.locks.TXLockId) LoggingThreadGroup(org.apache.geode.internal.logging.LoggingThreadGroup) ReplyException(org.apache.geode.distributed.internal.ReplyException)

Example 2 with TXLockId

use of org.apache.geode.internal.cache.locks.TXLockId in project geode by apache.

the class TXFarSideCMTracker method commitProcessReceived.

/**
   * Answers fellow "Far Siders" question about an DACK transaction when the transaction originator
   * died before it sent the CommitProcess message.
   */
public boolean commitProcessReceived(Object key, DM dm) {
    // transaction messages
    if (key instanceof TXLockId) {
        TXLockId lk = (TXLockId) key;
        waitForMemberToDepart(lk.getMemberId(), dm);
    } else if (key instanceof TXId) {
        TXId id = (TXId) key;
        waitForMemberToDepart(id.getMemberId(), dm);
    } else {
        Assert.assertTrue(false, "TXTracker received an unknown key class: " + key.getClass());
    }
    final TXCommitMessage mess;
    synchronized (this.txInProgress) {
        mess = (TXCommitMessage) this.txInProgress.get(key);
        if (null != mess && mess.isProcessing()) {
            return true;
        }
        for (int i = this.txHistory.length - 1; i >= 0; --i) {
            if (key.equals(this.txHistory[i])) {
                return true;
            }
        }
    }
    if (mess != null) {
        synchronized (mess) {
            if (!mess.isProcessing()) {
                // Prevent any potential future processing
                // of this message
                mess.setDontProcess();
                return false;
            } else {
                return true;
            }
        }
    }
    return false;
}
Also used : TXLockId(org.apache.geode.internal.cache.locks.TXLockId)

Aggregations

TXLockId (org.apache.geode.internal.cache.locks.TXLockId)2 DistributedMember (org.apache.geode.distributed.DistributedMember)1 ReplyException (org.apache.geode.distributed.internal.ReplyException)1 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)1 LoggingThreadGroup (org.apache.geode.internal.logging.LoggingThreadGroup)1