Ejemplo n.º 1
0
 private void checkDrainCondition() {
   // Don't ever go backwards once the drain decision is made.
   if (m_mustDrain) {
     return;
   }
   // if we've got things to sequence, check to if we're blocked
   if (!m_replayEntries.isEmpty()) {
     ReplayEntry head = m_replayEntries.firstEntry().getValue();
     if (!head.isReady()) {
       // if we're blocked, see if we have a sentinel or a fragment.
       // we know we have one or the other but not both.  Neither
       // means we wouldn't exist, and both would make us ready.
       // if it's the sentinel, see if the MPI's command log is done
       if (head.hasSentinel() && m_mpiEOLReached) {
         m_mustDrain = true;
       }
     }
   }
 }
Ejemplo n.º 2
0
  // Offer a new message. Return false if the offered message can be run immediately.
  public boolean offer(long inTxnId, TransactionInfoBaseMessage in) {
    ReplayEntry found = m_replayEntries.get(inTxnId);

    if (in instanceof Iv2EndOfLogMessage) {
      m_mpiEOLReached = true;
      return true;
    }

    if (in instanceof MultiPartitionParticipantMessage) {
      /*
       * DR sends multiple @LoadMultipartitionTable proc calls with the
       * same txnId, which is the snapshot txnId. For each partition,
       * there is a sentinel paired with the @LoadMultipartitionTable
       * call. Dedupe the sentinels the same way as we dedupe fragments,
       * so that there won't be sentinels end up in the sequencer where
       * matching fragments are deduped.
       */
      if (inTxnId <= m_lastPolledFragmentTxnId) {
        return true;
      }

      if (found == null) {
        ReplayEntry newEntry = new ReplayEntry();
        newEntry.m_sentinalTxnId = inTxnId;
        m_replayEntries.put(inTxnId, newEntry);
      } else {
        found.m_sentinalTxnId = inTxnId;
        assert (found.isReady());
      }
    } else if (in instanceof FragmentTaskMessage) {
      // already sequenced
      if (inTxnId <= m_lastPolledFragmentTxnId) {
        return false;
      }

      FragmentTaskMessage ftm = (FragmentTaskMessage) in;
      if (found == null) {
        ReplayEntry newEntry = new ReplayEntry();
        newEntry.m_firstFragment = ftm;
        m_replayEntries.put(inTxnId, newEntry);
      } else if (found.m_firstFragment == null) {
        found.m_firstFragment = ftm;
        assert (found.isReady());
      } else {
        found.addFragmentMessage(ftm);
      }
    } else if (in instanceof CompleteTransactionMessage) {
      CompleteTransactionMessage ctm = (CompleteTransactionMessage) in;
      // already sequenced
      if (inTxnId <= m_lastPolledFragmentTxnId) {
        if (found != null && found.m_firstFragment != null) {
          found.markLastFragment(ctm);
        }
        return false;
      }
      if (found != null && found.m_firstFragment != null) {
        found.addCompletedMessage(ctm);
      } else {
        // Always expect to see the fragment first, but there are places in the protocol
        // where CompleteTransactionMessages may arrive for transactions that this site hasn't
        // done/won't do, e.g. txn restart, so just tell the caller that we can't do
        // anything with it and hope the right thing happens.
        return false;
      }

    } else {
      if (dedupe(inTxnId, in) != null) {
        // Ignore an already seen txn
        return true;
      }
      updateLastSeenTxnId(inTxnId, in);

      if (m_replayEntries.isEmpty() || !m_replayEntries.lastEntry().getValue().hasSentinel()) {
        // not-blocked work; rejected and not queued.
        return false;
      } else {
        // blocked work queues with the newest replayEntry
        m_replayEntries.lastEntry().getValue().addBlockedMessage(in);
      }
    }
    return true;
  }